fomantic-ui-sass 2.9.2 → 2.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/app/assets/javascripts/semantic-ui/accordion.js +1 -5
  4. data/app/assets/javascripts/semantic-ui/api.js +22 -15
  5. data/app/assets/javascripts/semantic-ui/calendar.js +1 -6
  6. data/app/assets/javascripts/semantic-ui/checkbox.js +4 -6
  7. data/app/assets/javascripts/semantic-ui/dimmer.js +1 -5
  8. data/app/assets/javascripts/semantic-ui/dropdown.js +56 -33
  9. data/app/assets/javascripts/semantic-ui/embed.js +1 -6
  10. data/app/assets/javascripts/semantic-ui/flyout.js +40 -58
  11. data/app/assets/javascripts/semantic-ui/form.js +102 -53
  12. data/app/assets/javascripts/semantic-ui/modal.js +45 -33
  13. data/app/assets/javascripts/semantic-ui/nag.js +17 -9
  14. data/app/assets/javascripts/semantic-ui/popup.js +27 -19
  15. data/app/assets/javascripts/semantic-ui/progress.js +1 -6
  16. data/app/assets/javascripts/semantic-ui/rating.js +1 -5
  17. data/app/assets/javascripts/semantic-ui/search.js +4 -7
  18. data/app/assets/javascripts/semantic-ui/shape.js +1 -5
  19. data/app/assets/javascripts/semantic-ui/sidebar.js +15 -38
  20. data/app/assets/javascripts/semantic-ui/site.js +1 -1
  21. data/app/assets/javascripts/semantic-ui/slider.js +130 -34
  22. data/app/assets/javascripts/semantic-ui/state.js +23 -20
  23. data/app/assets/javascripts/semantic-ui/sticky.js +17 -16
  24. data/app/assets/javascripts/semantic-ui/tab.js +18 -8
  25. data/app/assets/javascripts/semantic-ui/toast.js +17 -9
  26. data/app/assets/javascripts/semantic-ui/transition.js +2 -6
  27. data/app/assets/javascripts/semantic-ui/visibility.js +15 -6
  28. data/app/assets/stylesheets/semantic-ui/collections/_breadcrumb.scss +1 -1
  29. data/app/assets/stylesheets/semantic-ui/collections/_form.scss +53 -20
  30. data/app/assets/stylesheets/semantic-ui/collections/_grid.scss +107 -107
  31. data/app/assets/stylesheets/semantic-ui/collections/_menu.scss +13 -7
  32. data/app/assets/stylesheets/semantic-ui/collections/_message.scss +1 -1
  33. data/app/assets/stylesheets/semantic-ui/collections/_table.scss +65 -1
  34. data/app/assets/stylesheets/semantic-ui/elements/_button.scss +2 -2
  35. data/app/assets/stylesheets/semantic-ui/elements/_container.scss +62 -1
  36. data/app/assets/stylesheets/semantic-ui/elements/_divider.scss +1 -1
  37. data/app/assets/stylesheets/semantic-ui/elements/_emoji.scss +697 -249
  38. data/app/assets/stylesheets/semantic-ui/elements/_flag.scss +3 -2
  39. data/app/assets/stylesheets/semantic-ui/elements/_header.scss +1 -1
  40. data/app/assets/stylesheets/semantic-ui/elements/_icon.scss +62 -62
  41. data/app/assets/stylesheets/semantic-ui/elements/_image.scss +1 -1
  42. data/app/assets/stylesheets/semantic-ui/elements/_input.scss +3 -27
  43. data/app/assets/stylesheets/semantic-ui/elements/_label.scss +21 -2
  44. data/app/assets/stylesheets/semantic-ui/elements/_list.scss +13 -13
  45. data/app/assets/stylesheets/semantic-ui/elements/_loader.scss +282 -282
  46. data/app/assets/stylesheets/semantic-ui/elements/_placeholder.scss +1 -1
  47. data/app/assets/stylesheets/semantic-ui/elements/_rail.scss +1 -1
  48. data/app/assets/stylesheets/semantic-ui/elements/_reveal.scss +1 -1
  49. data/app/assets/stylesheets/semantic-ui/elements/_segment.scss +161 -34
  50. data/app/assets/stylesheets/semantic-ui/elements/_step.scss +1 -1
  51. data/app/assets/stylesheets/semantic-ui/elements/_text.scss +1 -1
  52. data/app/assets/stylesheets/semantic-ui/globals/_reset.scss +1 -1
  53. data/app/assets/stylesheets/semantic-ui/globals/_site.scss +1 -1
  54. data/app/assets/stylesheets/semantic-ui/modules/_accordion.scss +1 -1
  55. data/app/assets/stylesheets/semantic-ui/modules/_calendar.scss +145 -8
  56. data/app/assets/stylesheets/semantic-ui/modules/_checkbox.scss +50 -6
  57. data/app/assets/stylesheets/semantic-ui/modules/_dimmer.scss +3 -3
  58. data/app/assets/stylesheets/semantic-ui/modules/_dropdown.scss +119 -26
  59. data/app/assets/stylesheets/semantic-ui/modules/_embed.scss +1 -1
  60. data/app/assets/stylesheets/semantic-ui/modules/_flyout.scss +1 -1
  61. data/app/assets/stylesheets/semantic-ui/modules/_modal.scss +10 -3
  62. data/app/assets/stylesheets/semantic-ui/modules/_nag.scss +1 -1
  63. data/app/assets/stylesheets/semantic-ui/modules/_popup.scss +41 -40
  64. data/app/assets/stylesheets/semantic-ui/modules/_progress.scss +1 -1
  65. data/app/assets/stylesheets/semantic-ui/modules/_rating.scss +1 -1
  66. data/app/assets/stylesheets/semantic-ui/modules/_search.scss +26 -1
  67. data/app/assets/stylesheets/semantic-ui/modules/_shape.scss +1 -1
  68. data/app/assets/stylesheets/semantic-ui/modules/_sidebar.scss +1 -1
  69. data/app/assets/stylesheets/semantic-ui/modules/_slider.scss +1 -1
  70. data/app/assets/stylesheets/semantic-ui/modules/_sticky.scss +1 -1
  71. data/app/assets/stylesheets/semantic-ui/modules/_tab.scss +1 -1
  72. data/app/assets/stylesheets/semantic-ui/modules/_toast.scss +6 -1
  73. data/app/assets/stylesheets/semantic-ui/modules/_transition.scss +1 -1
  74. data/app/assets/stylesheets/semantic-ui/views/_ad.scss +1 -1
  75. data/app/assets/stylesheets/semantic-ui/views/_card.scss +1 -1
  76. data/app/assets/stylesheets/semantic-ui/views/_comment.scss +6 -1
  77. data/app/assets/stylesheets/semantic-ui/views/_feed.scss +486 -5
  78. data/app/assets/stylesheets/semantic-ui/views/_item.scss +6 -1
  79. data/app/assets/stylesheets/semantic-ui/views/_statistic.scss +1 -1
  80. data/lib/fomantic/ui/sass/version.rb +2 -2
  81. metadata +1 -1
@@ -28,15 +28,25 @@
28
28
  $head = $('head'),
29
29
  $body = $('body'),
30
30
 
31
- moduleSelector = $allModules.selector || '',
32
-
33
31
  time = Date.now(),
34
32
  performance = [],
35
33
 
36
34
  query = arguments[0],
37
35
  methodInvoked = typeof query === 'string',
38
36
  queryArguments = [].slice.call(arguments, 1),
37
+ contextCheck = function (context, win) {
38
+ var $context;
39
+ if ([window, document].indexOf(context) >= 0) {
40
+ $context = $body;
41
+ } else {
42
+ $context = $(win.document).find(context);
43
+ if ($context.length === 0) {
44
+ $context = win.frameElement ? contextCheck(context, win.parent) : $body;
45
+ }
46
+ }
39
47
 
48
+ return $context;
49
+ },
40
50
  returnedValue
41
51
  ;
42
52
 
@@ -57,7 +67,7 @@
57
67
  moduleNamespace = 'module-' + namespace,
58
68
 
59
69
  $module = $(this),
60
- $context = [window, document].indexOf(settings.context) < 0 ? $document.find(settings.context) : $body,
70
+ $context = contextCheck(settings.context, window),
61
71
  $closeIcon = $module.find(selector.close),
62
72
  $inputs,
63
73
  $focusedElement,
@@ -76,6 +86,7 @@
76
86
  initialBodyMargin = '',
77
87
  tempBodyMargin = '',
78
88
  hadScrollbar = false,
89
+ windowRefocused = false,
79
90
 
80
91
  elementNamespace,
81
92
  id,
@@ -222,9 +233,6 @@
222
233
  .off(eventNamespace)
223
234
  .removeData(moduleNamespace)
224
235
  ;
225
- if (module.is.ios()) {
226
- module.remove.ios();
227
- }
228
236
  $closeIcon.off(elementNamespace);
229
237
  if ($inputs) {
230
238
  $inputs.off(elementNamespace);
@@ -254,9 +262,13 @@
254
262
  module.setup.heights();
255
263
  },
256
264
  focus: function () {
257
- if (module.is.visible() && settings.autofocus && settings.dimPage) {
265
+ windowRefocused = true;
266
+ },
267
+ click: function (event) {
268
+ if (windowRefocused && document.activeElement !== event.target && module.is.visible() && settings.autofocus && settings.dimPage && $(document.activeElement).closest(selector.flyout).length === 0) {
258
269
  requestAnimationFrame(module.set.autofocus);
259
270
  }
271
+ windowRefocused = false;
260
272
  },
261
273
  clickaway: function (event) {
262
274
  if (settings.closable) {
@@ -363,6 +375,9 @@
363
375
  $window
364
376
  .on('focus' + elementNamespace, module.event.focus)
365
377
  ;
378
+ $context
379
+ .on('click' + elementNamespace, module.event.click)
380
+ ;
366
381
  },
367
382
  clickaway: function () {
368
383
  module.verbose('Adding clickaway events to context', $context);
@@ -492,11 +507,12 @@
492
507
 
493
508
  return nodes;
494
509
  },
495
- shouldRefreshInputs = false
510
+ shouldRefreshInputs = false,
511
+ ignoreAutofocus = true
496
512
  ;
497
513
  mutations.every(function (mutation) {
498
514
  if (mutation.type === 'attributes') {
499
- if (observeAttributes && (mutation.attributeName === 'disabled' || $(mutation.target).find(':input').addBack(':input').length > 0)) {
515
+ if (observeAttributes && (mutation.attributeName === 'disabled' || $(mutation.target).find(':input').addBack(':input').filter(':visible').length > 0)) {
500
516
  shouldRefreshInputs = true;
501
517
  }
502
518
  } else {
@@ -506,6 +522,9 @@
506
522
  $removedInputs = $(collectNodes(mutation.removedNodes)).filter('a[href], [tabindex], :input');
507
523
  if ($addedInputs.length > 0 || $removedInputs.length > 0) {
508
524
  shouldRefreshInputs = true;
525
+ if ($addedInputs.filter(':input').length > 0 || $removedInputs.filter(':input').length > 0) {
526
+ ignoreAutofocus = false;
527
+ }
509
528
  }
510
529
  }
511
530
 
@@ -513,7 +532,7 @@
513
532
  });
514
533
 
515
534
  if (shouldRefreshInputs) {
516
- module.refreshInputs();
535
+ module.refreshInputs(ignoreAutofocus);
517
536
  }
518
537
  });
519
538
  observer.observe(element, {
@@ -527,7 +546,7 @@
527
546
  },
528
547
  refresh: function () {
529
548
  module.verbose('Refreshing selector cache');
530
- $context = [window, document].indexOf(settings.context) < 0 ? $document.find(settings.context) : $body;
549
+ $context = contextCheck(settings.context, window);
531
550
  module.refreshFlyouts();
532
551
  $pusher = $context.children(selector.pusher);
533
552
  module.clear.cache();
@@ -538,7 +557,7 @@
538
557
  $flyouts = $context.children(selector.flyout);
539
558
  },
540
559
 
541
- refreshInputs: function () {
560
+ refreshInputs: function (ignoreAutofocus) {
542
561
  if ($inputs) {
543
562
  $inputs
544
563
  .off('keydown' + elementNamespace)
@@ -550,8 +569,8 @@
550
569
  $inputs = $module.find('a[href], [tabindex], :input:enabled').filter(':visible').filter(function () {
551
570
  return $(this).closest('.disabled').length === 0;
552
571
  });
553
- if ($inputs.length === 0) {
554
- $inputs = $module;
572
+ if ($inputs.filter(':input').length === 0) {
573
+ $inputs = $module.add($inputs);
555
574
  $module.attr('tabindex', -1);
556
575
  } else {
557
576
  $module.removeAttr('tabindex');
@@ -562,7 +581,7 @@
562
581
  $inputs.last()
563
582
  .on('keydown' + elementNamespace, module.event.inputKeyDown.last)
564
583
  ;
565
- if (settings.autofocus && $inputs.filter(':focus').length === 0) {
584
+ if (!ignoreAutofocus && settings.autofocus && $inputs.filter(':focus').length === 0) {
566
585
  module.set.autofocus();
567
586
  }
568
587
  },
@@ -840,20 +859,14 @@
840
859
  var
841
860
  $autofocus = $inputs.filter('[autofocus]'),
842
861
  $rawInputs = $inputs.filter(':input'),
843
- $input = $autofocus.length > 0
844
- ? $autofocus.first()
862
+ $input = ($autofocus.length > 0
863
+ ? $autofocus
845
864
  : ($rawInputs.length > 0
846
865
  ? $rawInputs
847
- : $inputs.filter(':not(i.close)')
848
- ).first()
866
+ : $module)
867
+ ).first()
849
868
  ;
850
- // check if only the close icon is remaining
851
- if ($input.length === 0 && $inputs.length > 0) {
852
- $input = $inputs.first();
853
- }
854
- if ($input.length > 0) {
855
- $input.trigger('focus');
856
- }
869
+ $input.trigger('focus');
857
870
  },
858
871
  dimmerStyles: function () {
859
872
  if (settings.blurring) {
@@ -874,12 +887,6 @@
874
887
  });
875
888
  },
876
889
 
877
- // ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios
878
- // (This is no longer necessary in latest iOS)
879
- ios: function () {
880
- $html.addClass(className.ios);
881
- },
882
-
883
890
  // container
884
891
  pushed: function () {
885
892
  $context.addClass(className.pushed);
@@ -929,11 +936,6 @@
929
936
  ;
930
937
  },
931
938
 
932
- // ios scroll on html not document
933
- ios: function () {
934
- $html.removeClass(className.ios);
935
- },
936
-
937
939
  // context
938
940
  pushed: function () {
939
941
  $context.removeClass(className.pushed);
@@ -1055,20 +1057,6 @@
1055
1057
 
1056
1058
  return module.cache.isIE;
1057
1059
  },
1058
- ios: function () {
1059
- var
1060
- userAgent = navigator.userAgent,
1061
- isIOS = userAgent.match(regExp.ios),
1062
- isMobileChrome = userAgent.match(regExp.mobileChrome)
1063
- ;
1064
- if (isIOS && !isMobileChrome) {
1065
- module.verbose('Browser was found to be iOS', userAgent);
1066
-
1067
- return true;
1068
- }
1069
-
1070
- return false;
1071
- },
1072
1060
  mobile: function () {
1073
1061
  var
1074
1062
  userAgent = navigator.userAgent,
@@ -1231,7 +1219,7 @@
1231
1219
  });
1232
1220
  }
1233
1221
  clearTimeout(module.performance.timer);
1234
- module.performance.timer = setTimeout(module.performance.display, 500);
1222
+ module.performance.timer = setTimeout(function () { module.performance.display(); }, 500);
1235
1223
  },
1236
1224
  display: function () {
1237
1225
  var
@@ -1244,9 +1232,6 @@
1244
1232
  totalTime += data['Execution Time'];
1245
1233
  });
1246
1234
  title += ' ' + totalTime + 'ms';
1247
- if (moduleSelector) {
1248
- title += ' \'' + moduleSelector + '\'';
1249
- }
1250
1235
  if (performance.length > 0) {
1251
1236
  console.groupCollapsed(title);
1252
1237
  if (console.table) {
@@ -1418,7 +1403,6 @@
1418
1403
  blurring: 'blurring',
1419
1404
  closing: 'closing',
1420
1405
  dimmed: 'dimmed',
1421
- ios: 'ios',
1422
1406
  locked: 'locked',
1423
1407
  pushable: 'pushable',
1424
1408
  pushed: 'pushed',
@@ -1451,8 +1435,6 @@
1451
1435
  },
1452
1436
 
1453
1437
  regExp: {
1454
- ios: /(iPad|iPhone|iPod)/g,
1455
- mobileChrome: /(CriOS)/g,
1456
1438
  mobile: /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/g,
1457
1439
  },
1458
1440
 
@@ -22,7 +22,7 @@
22
22
  $.fn.form = function (parameters) {
23
23
  var
24
24
  $allModules = $(this),
25
- moduleSelector = $allModules.selector || '',
25
+ $window = $(window),
26
26
 
27
27
  time = Date.now(),
28
28
  performance = [],
@@ -61,6 +61,8 @@
61
61
  namespace,
62
62
  moduleNamespace,
63
63
  eventNamespace,
64
+ attachEventsSelector,
65
+ attachEventsAction,
64
66
 
65
67
  submitting = false,
66
68
  dirty = false,
@@ -75,6 +77,7 @@
75
77
  initialize: function () {
76
78
  // settings grabbed at run time
77
79
  module.get.settings();
80
+ $module.addClass(className.initial);
78
81
  if (methodInvoked) {
79
82
  if (instance === undefined) {
80
83
  module.instantiate();
@@ -128,10 +131,13 @@
128
131
  module.bindEvents();
129
132
  },
130
133
 
131
- submit: function () {
134
+ submit: function (event) {
132
135
  module.verbose('Submitting form', $module);
133
136
  submitting = true;
134
137
  $module.trigger('submit');
138
+ if (event) {
139
+ event.preventDefault();
140
+ }
135
141
  },
136
142
 
137
143
  attachEvents: function (selector, action) {
@@ -143,6 +149,9 @@
143
149
  module[action]();
144
150
  event.preventDefault();
145
151
  });
152
+
153
+ attachEventsSelector = selector;
154
+ attachEventsAction = action;
146
155
  },
147
156
 
148
157
  bindEvents: function () {
@@ -154,6 +163,7 @@
154
163
  .on('click' + eventNamespace, selector.reset, module.reset)
155
164
  .on('click' + eventNamespace, selector.clear, module.clear)
156
165
  ;
166
+ $field.on('invalid' + eventNamespace, module.event.field.invalid);
157
167
  if (settings.keyboardShortcuts) {
158
168
  $module.on('keydown' + eventNamespace, selector.field, module.event.field.keydown);
159
169
  }
@@ -168,10 +178,14 @@
168
178
 
169
179
  // Dirty events
170
180
  if (settings.preventLeaving) {
171
- $(window).on('beforeunload' + eventNamespace, module.event.beforeUnload);
181
+ $window.on('beforeunload' + eventNamespace, module.event.beforeUnload);
172
182
  }
173
183
 
174
- $field.on('change click keyup keydown blur', function (e) {
184
+ $field.on('change' + eventNamespace
185
+ + ' click' + eventNamespace
186
+ + ' keyup' + eventNamespace
187
+ + ' keydown' + eventNamespace
188
+ + ' blur' + eventNamespace, function (e) {
175
189
  module.determine.isDirty();
176
190
  });
177
191
 
@@ -182,6 +196,9 @@
182
196
  $module.on('clean' + eventNamespace, function (e) {
183
197
  settings.onClean.call();
184
198
  });
199
+ if (attachEventsSelector) {
200
+ module.attachEvents(attachEventsSelector, attachEventsAction);
201
+ }
185
202
  },
186
203
 
187
204
  clear: function () {
@@ -230,6 +247,7 @@
230
247
  isCheckbox = $field.is(selector.checkbox),
231
248
  isDropdown = $element.is(selector.uiDropdown) && module.can.useElement('dropdown'),
232
249
  isCalendar = $calendar.length > 0 && module.can.useElement('calendar'),
250
+ isFile = $field.is(selector.file),
233
251
  isErrored = $fieldGroup.hasClass(className.error)
234
252
  ;
235
253
  if (defaultValue === undefined) {
@@ -250,7 +268,7 @@
250
268
  $calendar.calendar('set date', defaultValue);
251
269
  } else {
252
270
  module.verbose('Resetting field value', $field, defaultValue);
253
- $field.val(defaultValue);
271
+ $field.val(isFile ? '' : defaultValue);
254
272
  }
255
273
  });
256
274
  module.remove.states();
@@ -261,8 +279,12 @@
261
279
  var
262
280
  allValid = true
263
281
  ;
264
- $.each(validation, function (fieldName, field) {
265
- if (!module.validate.field(field, fieldName, true)) {
282
+ $field.each(function (index, el) {
283
+ var $el = $(el),
284
+ validation = module.get.validation($el) || {},
285
+ identifier = module.get.identifier(validation, $el)
286
+ ;
287
+ if (!module.validate.field(validation, identifier, true)) {
266
288
  allValid = false;
267
289
  }
268
290
  });
@@ -386,6 +408,13 @@
386
408
  $module.off(eventNamespace);
387
409
  $field.off(eventNamespace);
388
410
  $submit.off(eventNamespace);
411
+ if (settings.preventLeaving) {
412
+ $window.off(eventNamespace);
413
+ }
414
+ if (attachEventsSelector) {
415
+ $(attachEventsSelector).off(eventNamespace);
416
+ attachEventsSelector = undefined;
417
+ }
389
418
  },
390
419
 
391
420
  event: {
@@ -411,9 +440,8 @@
411
440
  if (!event.ctrlKey && key === keyCode.enter && isInput && !isInDropdown && !isCheckbox) {
412
441
  if (!keyHeldDown) {
413
442
  $field.one('keyup' + eventNamespace, module.event.field.keyup);
414
- module.submit();
443
+ module.submit(event);
415
444
  module.debug('Enter pressed on input submitting form');
416
- event.preventDefault();
417
445
  }
418
446
  keyHeldDown = true;
419
447
  }
@@ -421,15 +449,18 @@
421
449
  keyup: function () {
422
450
  keyHeldDown = false;
423
451
  },
452
+ invalid: function (event) {
453
+ event.preventDefault();
454
+ },
424
455
  blur: function (event) {
425
456
  var
426
457
  $field = $(this),
427
- $fieldGroup = $field.closest($group),
428
- validationRules = module.get.validation($field)
458
+ validationRules = module.get.validation($field) || {},
459
+ identifier = module.get.identifier(validationRules, $field)
429
460
  ;
430
- if (validationRules && (settings.on === 'blur' || ($fieldGroup.hasClass(className.error) && settings.revalidate))) {
461
+ if (settings.on === 'blur' || (!$module.hasClass(className.initial) && settings.revalidate)) {
431
462
  module.debug('Revalidating field', $field, validationRules);
432
- module.validate.field(validationRules);
463
+ module.validate.field(validationRules, identifier);
433
464
  if (!settings.inline) {
434
465
  module.validate.form(false, true);
435
466
  }
@@ -438,14 +469,14 @@
438
469
  change: function (event) {
439
470
  var
440
471
  $field = $(this),
441
- $fieldGroup = $field.closest($group),
442
- validationRules = module.get.validation($field)
472
+ validationRules = module.get.validation($field) || {},
473
+ identifier = module.get.identifier(validationRules, $field)
443
474
  ;
444
- if (validationRules && (settings.on === 'change' || ($fieldGroup.hasClass(className.error) && settings.revalidate))) {
475
+ if (settings.on === 'change' || (!$module.hasClass(className.initial) && settings.revalidate)) {
445
476
  clearTimeout(module.timer);
446
477
  module.timer = setTimeout(function () {
447
478
  module.debug('Revalidating field', $field, validationRules);
448
- module.validate.field(validationRules);
479
+ module.validate.field(validationRules, identifier);
449
480
  if (!settings.inline) {
450
481
  module.validate.form(false, true);
451
482
  }
@@ -487,18 +518,7 @@
487
518
  return rule.type;
488
519
  },
489
520
  changeEvent: function (type, $input) {
490
- if (type === 'checkbox' || type === 'radio' || type === 'hidden' || $input.is('select')) {
491
- return 'change';
492
- }
493
-
494
- return module.get.inputEvent();
495
- },
496
- inputEvent: function () {
497
- return document.createElement('input').oninput !== undefined
498
- ? 'input'
499
- : (document.createElement('input').onpropertychange !== undefined
500
- ? 'propertychange'
501
- : 'keyup');
521
+ return ['file', 'checkbox', 'radio', 'hidden'].indexOf(type) >= 0 || $input.is('select') ? 'change' : 'input';
502
522
  },
503
523
  fieldsFromShorthand: function (fields) {
504
524
  var
@@ -522,6 +542,9 @@
522
542
 
523
543
  return fullFields;
524
544
  },
545
+ identifier: function (validation, $el) {
546
+ return validation.identifier || $el.attr('id') || $el.attr('name') || $el.data(metadata.validate);
547
+ },
525
548
  prompt: function (rule, field) {
526
549
  var
527
550
  ruleName = module.get.ruleName(rule),
@@ -634,7 +657,7 @@
634
657
  var $field = typeof identifier === 'string'
635
658
  ? module.get.field(identifier)
636
659
  : identifier,
637
- $label = $field.closest(selector.group).find('label').eq(0)
660
+ $label = $field.closest(selector.group).find('label:not(:empty)').eq(0)
638
661
  ;
639
662
 
640
663
  return $label.length === 1
@@ -888,7 +911,8 @@
888
911
  $field = module.get.field(identifier),
889
912
  $fieldGroup = $field.closest($group),
890
913
  $prompt = $fieldGroup.children(selector.prompt),
891
- promptExists = $prompt.length > 0
914
+ promptExists = $prompt.length > 0,
915
+ canTransition = settings.transition && module.can.useElement('transition')
892
916
  ;
893
917
  module.verbose('Adding field error state', identifier);
894
918
  if (!internal) {
@@ -897,8 +921,22 @@
897
921
  ;
898
922
  }
899
923
  if (settings.inline) {
924
+ if (promptExists) {
925
+ if (canTransition) {
926
+ if ($prompt.transition('is animating')) {
927
+ $prompt.transition('stop all');
928
+ }
929
+ } else if ($prompt.is(':animated')) {
930
+ $prompt.stop(true, true);
931
+ }
932
+ $prompt = $fieldGroup.children(selector.prompt);
933
+ promptExists = $prompt.length > 0;
934
+ }
900
935
  if (!promptExists) {
901
936
  $prompt = $('<div/>').addClass(className.label);
937
+ if (!canTransition) {
938
+ $prompt.css('display', 'none');
939
+ }
902
940
  $prompt
903
941
  .appendTo($fieldGroup)
904
942
  ;
@@ -907,7 +945,7 @@
907
945
  .html(settings.templates.prompt(errors))
908
946
  ;
909
947
  if (!promptExists) {
910
- if (settings.transition && module.can.useElement('transition')) {
948
+ if (canTransition) {
911
949
  module.verbose('Displaying error with css transition', settings.transition);
912
950
  $prompt.transition(settings.transition + ' in', settings.duration);
913
951
  } else {
@@ -916,9 +954,9 @@
916
954
  .fadeIn(settings.duration)
917
955
  ;
918
956
  }
919
- } else {
920
- module.verbose('Inline errors are disabled, no inline error added', identifier);
921
957
  }
958
+ } else {
959
+ module.verbose('Inline errors are disabled, no inline error added', identifier);
922
960
  }
923
961
  },
924
962
  errors: function (errors) {
@@ -965,7 +1003,7 @@
965
1003
  $message.empty();
966
1004
  },
967
1005
  states: function () {
968
- $module.removeClass(className.error).removeClass(className.success);
1006
+ $module.removeClass(className.error).removeClass(className.success).addClass(className.initial);
969
1007
  if (!settings.inline) {
970
1008
  module.remove.errors();
971
1009
  }
@@ -1103,6 +1141,7 @@
1103
1141
  $field = module.get.field(key),
1104
1142
  $element = $field.parent(),
1105
1143
  $calendar = $field.closest(selector.uiCalendar),
1144
+ isFile = $field.is(selector.file),
1106
1145
  isMultiple = Array.isArray(value),
1107
1146
  isCheckbox = $element.is(selector.uiCheckbox) && module.can.useElement('checkbox'),
1108
1147
  isDropdown = $element.is(selector.uiDropdown) && module.can.useElement('dropdown'),
@@ -1145,7 +1184,7 @@
1145
1184
  $calendar.calendar('set date', value);
1146
1185
  } else {
1147
1186
  module.verbose('Setting field value', value, $field);
1148
- $field.val(value);
1187
+ $field.val(isFile ? '' : value);
1149
1188
  }
1150
1189
  }
1151
1190
  });
@@ -1201,7 +1240,7 @@
1201
1240
  return rule.type === 'empty';
1202
1241
  }) !== 0
1203
1242
  : false,
1204
- identifier = validation.identifier || $el.attr('id') || $el.attr('name') || $el.data(metadata.validate)
1243
+ identifier = module.get.identifier(validation, $el)
1205
1244
  ;
1206
1245
  if (isRequired && !isDisabled && !hasEmptyRule && identifier !== undefined) {
1207
1246
  if (isCheckbox) {
@@ -1233,7 +1272,7 @@
1233
1272
  if (keyHeldDown) {
1234
1273
  return false;
1235
1274
  }
1236
-
1275
+ $module.removeClass(className.initial);
1237
1276
  // reset errors
1238
1277
  formErrors = [];
1239
1278
  if (module.determine.isValid()) {
@@ -1305,13 +1344,25 @@
1305
1344
  ? module.get.field(field.depends)
1306
1345
  : false,
1307
1346
  fieldValid = true,
1308
- fieldErrors = []
1347
+ fieldErrors = [],
1348
+ isDisabled = $field.filter(':not(:disabled)').length === 0,
1349
+ validationMessage = $field[0].validationMessage,
1350
+ errorLimit
1309
1351
  ;
1310
1352
  if (!field.identifier) {
1311
1353
  module.debug('Using field name as identifier', identifier);
1312
1354
  field.identifier = identifier;
1313
1355
  }
1314
- var isDisabled = $field.filter(':not(:disabled)').length === 0;
1356
+ if (validationMessage) {
1357
+ module.debug('Field is natively invalid', identifier);
1358
+ fieldErrors.push(validationMessage);
1359
+ fieldValid = false;
1360
+ if (showErrors) {
1361
+ $field.closest($group).addClass(className.error);
1362
+ }
1363
+ } else if (showErrors) {
1364
+ $field.closest($group).removeClass(className.error);
1365
+ }
1315
1366
  if (isDisabled) {
1316
1367
  module.debug('Field is disabled. Skipping', identifier);
1317
1368
  } else if (field.optional && module.is.blank($field)) {
@@ -1319,11 +1370,9 @@
1319
1370
  } else if (field.depends && module.is.empty($dependsField)) {
1320
1371
  module.debug('Field depends on another value that is not present or empty. Skipping', $dependsField);
1321
1372
  } else if (field.rules !== undefined) {
1322
- if (showErrors) {
1323
- $field.closest($group).removeClass(className.error);
1324
- }
1373
+ errorLimit = field.errorLimit || settings.errorLimit;
1325
1374
  $.each(field.rules, function (index, rule) {
1326
- if (module.has.field(identifier)) {
1375
+ if (module.has.field(identifier) && (!errorLimit || fieldErrors.length < errorLimit)) {
1327
1376
  var invalidFields = module.validate.rule(field, rule, true) || [];
1328
1377
  if (invalidFields.length > 0) {
1329
1378
  module.debug('Field is invalid', identifier, rule.type);
@@ -1338,7 +1387,7 @@
1338
1387
  }
1339
1388
  if (fieldValid) {
1340
1389
  if (showErrors) {
1341
- module.remove.prompt(identifier, fieldErrors);
1390
+ module.remove.prompt(identifier);
1342
1391
  settings.onValid.call($field);
1343
1392
  }
1344
1393
  } else {
@@ -1460,7 +1509,7 @@
1460
1509
  });
1461
1510
  }
1462
1511
  clearTimeout(module.performance.timer);
1463
- module.performance.timer = setTimeout(module.performance.display, 500);
1512
+ module.performance.timer = setTimeout(function () { module.performance.display(); }, 500);
1464
1513
  },
1465
1514
  display: function () {
1466
1515
  var
@@ -1473,9 +1522,6 @@
1473
1522
  totalTime += data['Execution Time'];
1474
1523
  });
1475
1524
  title += ' ' + totalTime + 'ms';
1476
- if (moduleSelector) {
1477
- title += ' \'' + moduleSelector + '\'';
1478
- }
1479
1525
  if ($allModules.length > 1) {
1480
1526
  title += ' (' + $allModules.length + ')';
1481
1527
  }
@@ -1578,6 +1624,7 @@
1578
1624
  preventLeaving: false,
1579
1625
  errorFocus: true,
1580
1626
  dateHandling: 'date', // 'date', 'input', 'formatter'
1627
+ errorLimit: 0,
1581
1628
 
1582
1629
  onValid: function () {},
1583
1630
  onInvalid: function () {},
@@ -1631,8 +1678,8 @@
1631
1678
  isExactly: '{name} must be exactly "{ruleValue}"',
1632
1679
  not: '{name} cannot be set to "{ruleValue}"',
1633
1680
  notExactly: '{name} cannot be set to exactly "{ruleValue}"',
1634
- contain: '{name} must contain "{ruleValue}"',
1635
- containExactly: '{name} must contain exactly "{ruleValue}"',
1681
+ contains: '{name} must contain "{ruleValue}"',
1682
+ containsExactly: '{name} must contain exactly "{ruleValue}"',
1636
1683
  doesntContain: '{name} cannot contain "{ruleValue}"',
1637
1684
  doesntContainExactly: '{name} cannot contain exactly "{ruleValue}"',
1638
1685
  minLength: '{name} must be at least {ruleValue} characters',
@@ -1651,9 +1698,10 @@
1651
1698
  selector: {
1652
1699
  checkbox: 'input[type="checkbox"], input[type="radio"]',
1653
1700
  clear: '.clear',
1654
- field: 'input:not(.search):not([type="file"]):not([type="reset"]):not([type="button"]):not([type="submit"]), textarea, select',
1701
+ field: 'input:not(.search):not([type="reset"]):not([type="button"]):not([type="submit"]), textarea, select',
1702
+ file: 'input[type="file"]',
1655
1703
  group: '.field',
1656
- input: 'input:not([type="file"])',
1704
+ input: 'input',
1657
1705
  message: '.error.message',
1658
1706
  prompt: '.prompt.label',
1659
1707
  radio: 'input[type="radio"]',
@@ -1665,6 +1713,7 @@
1665
1713
  },
1666
1714
 
1667
1715
  className: {
1716
+ initial: 'initial',
1668
1717
  error: 'error',
1669
1718
  label: 'ui basic red pointing prompt label',
1670
1719
  pressed: 'down',