vuejs 1.0.35 → 1.0.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3fa23b8cab0da4e43e4f1612dcc4d3f3ad679f33
4
- data.tar.gz: f006633d5db58048e5112ceaf94fffdef5b05592
3
+ metadata.gz: 4c89036734f2509ae25b950c949bd85d013871a5
4
+ data.tar.gz: 3899c544794176ac2406654074688f6bdf921c8b
5
5
  SHA512:
6
- metadata.gz: 370919533736893068ed8b22f58791731144d4aadcbc3e349cbe5e37fad186d1ea2d86d202c39a43e1c4160eb661a786207d1fc5cd544f2b4b58975d2937b228
7
- data.tar.gz: e51c32ed559dcc782bd8d59d005898c18dc9780ab3a017aa2d5e85f600ba04adcf734571f9d7fc74bedd0bb9d7cb946779e0888b96521188bae77050ca31e29a
6
+ metadata.gz: dd47de0b0dac761cc8a4a763fb9d71582e4aa8d0067dccd15171a0c50e23d95690dc327b248b90f260d111f58b01f1aa8758b4b9d7866528b69c400a32dc81ed
7
+ data.tar.gz: '068873225e4d79640c96eadc5a224a673358dbbdbfe8eb1e03cb74b6ebce442814aed24db39df4c00a29450f567212a9c9852d647419cbfdd060dff8ad78d83a'
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  gem `vuejs` ships with the 1.x & 2.x latest [Vue.js + vue-router + vue-resource + vue-validator + vuex](http://vuejs.org/) and integrate with Rails' asset pipeline. Vue.js is created by Evan You and the vuejs team.
6
6
 
7
- The current 2.x version is `Vue.js` (v2.1.7) + `vue-router` (v2.1.1) + `vue-validator` (v2.1.3) + `vuex` (v2.1.1).
7
+ The current 2.x version is `Vue.js` (v2.1.8) + `vue-router` (v2.1.1) + `vue-validator` (v3.0.0-alpha.2) + `vuex` (v2.1.1).
8
8
  > Note that Vue 2.x is not compatible with 1.x. vue-router 2.0 only works with Vue 2.x`
9
9
 
10
10
  ##### Legacy
@@ -30,6 +30,17 @@ Or install it yourself as:
30
30
 
31
31
  ## Usage
32
32
 
33
+ For 2.x Vue & vue-router or Vue-validator
34
+ ```
35
+ //= require vue2
36
+ //= require vue-router2
37
+ //= require vue-validator
38
+ //= require vuex
39
+
40
+ ```
41
+
42
+
43
+
33
44
  For 1.x
34
45
 
35
46
  ```
@@ -42,15 +53,6 @@ For 1.x
42
53
  //= require_tree .
43
54
  ```
44
55
 
45
- For 2.x Vue & vue-router or Vue-validator
46
- ```
47
- //= require vue2
48
- //= require vue-router2
49
- //= require vue-validator
50
- //= require vuex
51
-
52
- ```
53
-
54
56
  ## Development
55
57
 
56
58
  After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,3 +1,3 @@
1
1
  module Vuejs
2
- VERSION = "1.0.35"
2
+ VERSION = "1.0.36"
3
3
  end
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * vue-validator v3.0.0-alpha.1
2
+ * vue-validator v3.0.0-alpha.2
3
3
  * (c) 2016 kazuya kawaguchi
4
4
  * Released under the MIT License.
5
5
  */
@@ -11,14 +11,6 @@
11
11
 
12
12
  /* */
13
13
 
14
- var inBrowser =
15
- typeof window !== 'undefined' &&
16
- Object.prototype.toString.call(window) !== '[object Object]';
17
- var UA = inBrowser && window.navigator.userAgent.toLowerCase();
18
- var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
19
-
20
- var MODEL_NOTIFY_EVENT = '__VUE_VALIDATOR_MODEL_NOTIFY_EVENT__';
21
-
22
14
  function warn (msg, err) {
23
15
  if (window.console) {
24
16
  console.warn('[vue-validator] ' + msg);
@@ -28,122 +20,6 @@ function warn (msg, err) {
28
20
  }
29
21
  }
30
22
 
31
- function looseEqual (a, b) {
32
- return a === b || (
33
- isObject(a) && isObject(b)
34
- ? JSON.stringify(a) === JSON.stringify(b)
35
- : false
36
- )
37
- }
38
-
39
- function getClass (el) {
40
- var classname = el.className;
41
- if (typeof classname === 'object') {
42
- classname = classname.baseVal || '';
43
- }
44
- return classname
45
- }
46
-
47
- function setClass (el, cls) {
48
- if (isIE9 && !/svg$/.test(el.namespaceURI)) {
49
- el.className = cls;
50
- } else {
51
- el.setAttribute('class', cls);
52
- }
53
- }
54
-
55
- function addClass (el, cls) {
56
- if (el.classList) {
57
- el.classList.add(cls);
58
- } else {
59
- var cur = ' ' + getClass(el) + ' ';
60
- if (cur.indexOf(' ' + cls + ' ') < 0) {
61
- setClass(el, (cur + cls).trim());
62
- }
63
- }
64
- }
65
-
66
- function removeClass (el, cls) {
67
- if (el.classList) {
68
- el.classList.remove(cls);
69
- } else {
70
- var cur = ' ' + getClass(el) + ' ';
71
- var tar = ' ' + cls + ' ';
72
- while (cur.indexOf(tar) >= 0) {
73
- cur = cur.replace(tar, ' ');
74
- }
75
- setClass(el, cur.trim());
76
- }
77
- if (!el.className) {
78
- el.removeAttribute('class');
79
- }
80
- }
81
-
82
- function toggleClasses (el, key, fn) {
83
- if (!el) { return }
84
-
85
- key = key.trim();
86
- if (key.indexOf(' ') === -1) {
87
- fn(el, key);
88
- return
89
- }
90
-
91
- var keys = key.split(/\s+/);
92
- for (var i = 0, l = keys.length; i < l; i++) {
93
- fn(el, keys[i]);
94
- }
95
- }
96
-
97
- function triggerEvent (el, event, fn) {
98
- var e = document.createEvent('HTMLEvents');
99
- e.initEvent(event, true, true);
100
- fn && fn(e);
101
- el.dispatchEvent(e);
102
- }
103
-
104
- // TODO: should be defined strict type
105
- function mapValidation (results) {
106
- var res = {};
107
-
108
- normalizeMap(results).forEach(function (ref) {
109
- var key = ref.key;
110
- var val = ref.val;
111
-
112
- res[key] = function mappedValidation () {
113
- var validation = this.$validation;
114
- if (!this._isMounted) {
115
- return null
116
- }
117
- var paths = val.split('.');
118
- var first = paths.shift();
119
- if (first !== '$validation') {
120
- warn(("unknown validation result path: " + val));
121
- return null
122
- }
123
- var path;
124
- var value = validation;
125
- do {
126
- path = paths.shift();
127
- value = value[path];
128
- } while (paths.length > 0)
129
- return value
130
- };
131
- });
132
-
133
- return res
134
- }
135
-
136
- function isObject (obj) {
137
- return obj !== null && typeof obj === 'object'
138
- }
139
-
140
- // TODO: should be defined strict type
141
- function normalizeMap (map) {
142
- return Array.isArray(map)
143
- ? map.map(function (key) { return ({ key: key, val: key }); })
144
- : Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); })
145
- }
146
-
147
23
  /* */
148
24
 
149
25
  // validator configrations
@@ -171,32 +47,33 @@ var Config = function (Vue) {
171
47
  * required
172
48
  * This function validate whether the value has been filled out.
173
49
  */
174
- function required (val) {
50
+ function required (val, arg) {
51
+ var isRequired = arg === undefined ? true : arg;
175
52
  if (Array.isArray(val)) {
176
53
  if (val.length !== 0) {
177
54
  var valid = true;
178
55
  for (var i = 0, l = val.length; i < l; i++) {
179
- valid = required(val[i]);
180
- if (!valid) {
56
+ valid = required(val[i], isRequired);
57
+ if ((isRequired && !valid) || (!isRequired && valid)) {
181
58
  break
182
59
  }
183
60
  }
184
61
  return valid
185
62
  } else {
186
- return false
63
+ return !isRequired
187
64
  }
188
65
  } else if (typeof val === 'number' || typeof val === 'function') {
189
- return true
66
+ return isRequired
190
67
  } else if (typeof val === 'boolean') {
191
- return val
68
+ return val === isRequired
192
69
  } else if (typeof val === 'string') {
193
- return val.length > 0
70
+ return isRequired ? (val.length > 0) : (val.length <= 0)
194
71
  } else if (val !== null && typeof val === 'object') {
195
- return Object.keys(val).length > 0
72
+ return isRequired ? (Object.keys(val).length > 0) : (Object.keys(val).length <= 0)
196
73
  } else if (val === null || val === undefined) {
197
- return false
74
+ return !isRequired
198
75
  } else {
199
- return false
76
+ return !isRequired
200
77
  }
201
78
  }
202
79
 
@@ -353,6 +230,13 @@ var Group = function (Vue) {
353
230
  var results = this.results;
354
231
  this._validityKeys.forEach(function (key) {
355
232
  ret[key] = results[key];
233
+ if (ret[key].errors) {
234
+ var errors = ret.errors || [];
235
+ ret[key].errors.forEach(function (error) {
236
+ errors.push(error);
237
+ });
238
+ ret.errors = errors;
239
+ }
356
240
  });
357
241
  return ret
358
242
  }
@@ -409,6 +293,9 @@ var Group = function (Vue) {
409
293
  this$1.resetResults(name);
410
294
  });
411
295
  },
296
+ validityCount: function validityCount () {
297
+ return this._validityKeys.length
298
+ },
412
299
  isRegistered: function isRegistered (name) {
413
300
  return name in this._validities
414
301
  },
@@ -543,20 +430,29 @@ var ValidationClass = function (Vue) {
543
430
  var namedValidity = named ? this._getValidityGroup('named', named) : null;
544
431
  if (named && group && namedValidity && groupValidity) {
545
432
  groupValidity.unregister(field);
546
- namedValidity.isRegistered(group) && namedValidity.unregister(group);
547
- this._validityManager.isRegistered(named) && this._validityManager.unregister(named);
548
- } else if (namedValidity) {
433
+ if (groupValidity.validityCount() === 0) {
434
+ namedValidity.isRegistered(group) && namedValidity.unregister(group);
435
+ this._unregisterValidityGroup('group', group);
436
+ }
437
+ if (namedValidity.validityCount() === 0) {
438
+ this._validityManager.isRegistered(named) && this._validityManager.unregister(named);
439
+ this._unregisterValidityGroup('named', named);
440
+ }
441
+ } else if (named && namedValidity) {
549
442
  namedValidity.unregister(field);
550
- this._validityManager.isRegistered(named) && this._validityManager.unregister(named);
551
- } else if (groupValidity) {
443
+ if (namedValidity.validityCount() === 0) {
444
+ this._validityManager.isRegistered(named) && this._validityManager.unregister(named);
445
+ this._unregisterValidityGroup('named', named);
446
+ }
447
+ } else if (group && groupValidity) {
552
448
  groupValidity.unregister(field);
553
- this._validityManager.isRegistered(group) && this._validityManager.unregister(group);
449
+ if (groupValidity.validityCount() === 0) {
450
+ this._validityManager.isRegistered(group) && this._validityManager.unregister(group);
451
+ this._unregisterValidityGroup('group', group);
452
+ }
554
453
  } else {
555
454
  this._validityManager.unregister(field);
556
455
  }
557
-
558
- group && this._unregisterValidityGroup('group', group);
559
- named && this._unregisterValidityGroup('named', named);
560
456
  };
561
457
 
562
458
  Validation.prototype.destroy = function destroy () {
@@ -669,6 +565,8 @@ var Mixin = function (Vue) {
669
565
  }
670
566
  };
671
567
 
568
+ /* */
569
+
672
570
  var baseProps = {
673
571
  field: {
674
572
  type: String,
@@ -684,31 +582,81 @@ var baseProps = {
684
582
  multiple: {
685
583
  type: Boolean
686
584
  },
585
+ autotouch: {
586
+ type: String,
587
+ default: function () {
588
+ return 'on'
589
+ }
590
+ },
687
591
  classes: {
688
592
  type: Object,
689
593
  default: function () {
690
- return {
691
- valid: 'valid',
692
- invalid: 'invalid',
693
- touched: 'touched',
694
- untouched: 'untouched',
695
- pristine: 'pristine',
696
- dirty: 'dirty',
697
- modified: 'modified'
698
- }
594
+ return {}
699
595
  }
700
596
  }
701
597
  };
702
598
 
599
+ var DEFAULT_CLASSES = {
600
+ valid: 'valid',
601
+ invalid: 'invalid',
602
+ touched: 'touched',
603
+ untouched: 'untouched',
604
+ pristine: 'pristine',
605
+ dirty: 'dirty',
606
+ modified: 'modified'
607
+ };
608
+
703
609
  /* */
704
610
  var States = function (Vue) {
705
611
  var ref = Vue.util;
706
612
  var extend = ref.extend;
613
+ var isPlainObject = ref.isPlainObject;
614
+
615
+ function initialStates (states, validators, init) {
616
+ if ( init === void 0 ) init = undefined;
617
+
618
+ if (Array.isArray(validators)) {
619
+ validators.forEach(function (validator) {
620
+ states[validator] = init;
621
+ });
622
+ } else {
623
+ Object.keys(validators).forEach(function (validator) {
624
+ var props = (validators[validator] &&
625
+ validators[validator]['props'] &&
626
+ isPlainObject(validators[validator]['props']))
627
+ ? validators[validator]['props']
628
+ : null;
629
+ if (props) {
630
+ Object.keys(props).forEach(function (prop) {
631
+ states[validator] = {};
632
+ states[validator][prop] = init;
633
+ });
634
+ } else {
635
+ states[validator] = init;
636
+ }
637
+ });
638
+ }
639
+ }
640
+
641
+ function getInitialResults (validators) {
642
+ var results = {};
643
+ initialStates(results, validators, undefined);
644
+ return results
645
+ }
646
+
647
+ function getInitialProgresses (validators) {
648
+ var progresses = {};
649
+ initialStates(progresses, validators, '');
650
+ return progresses
651
+ }
707
652
 
708
653
  var props = extend({
709
654
  child: {
710
655
  type: Object,
711
656
  required: true
657
+ },
658
+ value: {
659
+ type: Object
712
660
  }
713
661
  }, baseProps);
714
662
 
@@ -731,36 +679,52 @@ var States = function (Vue) {
731
679
  };
732
680
 
733
681
  function nomalizeValidators (target) {
734
- var validators;
735
- if (typeof target === 'string') {
736
- validators = [target];
737
- } else if (Array.isArray(target)) {
738
- validators = target;
739
- } else {
740
- validators = Object.keys(target);
741
- }
742
- return validators
743
- }
744
-
745
- function getInitialResults (validators) {
746
- var results = {};
747
- validators.forEach(function (validator) {
748
- results[validator] = undefined;
749
- });
750
- return results
751
- }
752
-
753
- function getInitialProgresses (validators) {
754
- var progresses = {};
755
- validators.forEach(function (validator) {
756
- progresses[validator] = '';
757
- });
758
- return progresses
682
+ return typeof target === 'string' ? [target] : target
759
683
  }
760
684
 
761
685
  /* */
762
686
 
763
687
  var Computed = function (Vue) {
688
+ var ref = Vue.util;
689
+ var isPlainObject = ref.isPlainObject;
690
+
691
+ function setError (
692
+ result,
693
+ field,
694
+ validator,
695
+ message,
696
+ prop
697
+ ) {
698
+ var error = { field: field, validator: validator };
699
+ if (message) {
700
+ error.message = message;
701
+ }
702
+ if (prop) {
703
+ error.prop = prop;
704
+ }
705
+ result.errors = result.errors || [];
706
+ result.errors.push(error);
707
+ }
708
+
709
+ function walkProgresses (keys, target) {
710
+ var progress = '';
711
+ for (var i = 0; i < keys.length; i++) {
712
+ var result = target[keys[i]];
713
+ if (typeof result === 'string' && result) {
714
+ progress = result;
715
+ break
716
+ }
717
+ if (isPlainObject(result)) {
718
+ var nestedKeys = Object.keys(result);
719
+ progress = walkProgresses(nestedKeys, result);
720
+ if (!progress) {
721
+ break
722
+ }
723
+ }
724
+ }
725
+ return progress
726
+ }
727
+
764
728
  function invalid () {
765
729
  return !this.valid
766
730
  }
@@ -788,106 +752,89 @@ var Computed = function (Vue) {
788
752
 
789
753
  var keys = this._keysCached(this._uid.toString(), this.results);
790
754
  keys.forEach(function (validator) {
791
- var result = getValidatorResult(validator, this$1.results[validator]);
792
- if (result === false) { // success
793
- ret[validator] = false;
794
- } else { // failed
795
- var error = { field: this$1.field, validator: validator };
796
- if (typeof result === 'string') {
797
- error.message = result;
798
- }
799
- if (!ret.errors) {
800
- ret.errors = [];
801
- }
802
- if (Array.isArray(ret.errors)) {
803
- ret.errors.push(error);
755
+ var result = this$1.results[validator];
756
+ if (typeof result === 'boolean') {
757
+ if (result) {
758
+ ret[validator] = false;
759
+ } else {
760
+ setError(ret, this$1.field, validator);
761
+ ret[validator] = !result;
804
762
  }
763
+ } else if (typeof result === 'string') {
764
+ setError(ret, this$1.field, validator, result);
805
765
  ret[validator] = result;
766
+ } else if (isPlainObject(result)) { // object
767
+ var props = Object.keys(result);
768
+ props.forEach(function (prop) {
769
+ var propRet = result[prop];
770
+ ret[prop] = ret[prop] || {};
771
+ if (typeof propRet === 'boolean') {
772
+ if (propRet) {
773
+ ret[prop][validator] = false;
774
+ } else {
775
+ setError(ret, this$1.field, validator, undefined, prop);
776
+ ret[prop][validator] = !propRet;
777
+ }
778
+ } else if (typeof propRet === 'string') {
779
+ setError(ret, this$1.field, validator, propRet, prop);
780
+ ret[prop][validator] = propRet;
781
+ } else {
782
+ ret[prop][validator] = false;
783
+ }
784
+ });
785
+ } else {
786
+ ret[validator] = false;
806
787
  }
807
788
  });
808
789
 
809
790
  return ret
810
791
  }
811
792
 
793
+ function progress () {
794
+ var ret = '';
795
+ ret = walkProgresses(
796
+ this._keysCached(this._uid.toString(), this.results),
797
+ this.progresses
798
+ );
799
+ return ret
800
+ }
801
+
812
802
  return {
813
803
  invalid: invalid,
814
804
  pristine: pristine,
815
805
  untouched: untouched,
816
- result: result
806
+ result: result,
807
+ progress: progress
817
808
  }
818
809
  };
819
810
 
820
- function getValidatorResult (
821
- validator,
822
- result
823
- ) {
824
- if (typeof result === 'boolean' && !result) {
825
- return true
826
- }
827
-
828
- if (typeof result === 'string' && result) {
829
- return result
830
- }
831
-
832
- return false
833
- }
834
-
835
811
  /* */
836
812
 
837
813
  var Render = function (Vue) {
838
814
  return {
839
815
  render: function render (h) {
840
- this._interceptEvents(this.child, this.multiple);
841
816
  return this.child
842
817
  }
843
818
  }
844
819
  };
845
820
 
846
821
  /* */
847
- function addEventInfo (e) {
848
- e[MODEL_NOTIFY_EVENT] = 'DOM';
849
- }
850
-
851
- function modelValueEqual (vnode) {
852
- var directives = (vnode.data && vnode.data.directives) || [];
853
- var directive = directives.find(function (dir) {
854
- return dir.name === 'model'
855
- });
856
- return !directive
857
- ? null
858
- : looseEqual(directive.value, directive.oldValue)
859
- }
860
-
861
- /* */
862
- var SingleElement = function SingleElement (vm, vnode) {
863
- this._vm = vm;
864
- this._vnode = vnode;
865
- this.initValue = this.getValue();
866
- this.attachValidity();
867
- };
868
822
 
869
- var prototypeAccessors = { _isBuiltIn: {},_isComponent: {} };
870
-
871
- prototypeAccessors._isBuiltIn.get = function () {
872
- var vnode = this._vnode;
873
- return !vnode.child &&
874
- !vnode.componentOptions &&
875
- vnode.tag
876
- };
823
+ var SingleElementClass = function (Vue) {
824
+ var ref = Vue.util;
825
+ var looseEqual = ref.looseEqual;
877
826
 
878
- prototypeAccessors._isComponent.get = function () {
879
- var vnode = this._vnode;
880
- return vnode.child &&
881
- vnode.componentOptions &&
882
- vnode.tag.match(/vue-component/)
883
- };
827
+ var SingleElement = function SingleElement (vm) {
828
+ this._vm = vm;
829
+ this.initValue = this.getValue();
830
+ this.attachValidity();
831
+ };
884
832
 
885
- SingleElement.prototype.attachValidity = function attachValidity () {
886
- this._vm.$el.$validity = this._vm;
887
- };
833
+ SingleElement.prototype.attachValidity = function attachValidity () {
834
+ this._vm.$el.$validity = this._vm;
835
+ };
888
836
 
889
- SingleElement.prototype.getValue = function getValue () {
890
- if (this._isBuiltIn) {
837
+ SingleElement.prototype.getValue = function getValue () {
891
838
  var el = this._vm.$el;
892
839
  if (el.tagName === 'SELECT') {
893
840
  return getSelectValue(el)
@@ -898,16 +845,9 @@ SingleElement.prototype.getValue = function getValue () {
898
845
  return el.value
899
846
  }
900
847
  }
901
- } else if (this._isComponent) {
902
- return this._vnode.child.value
903
- } else {
904
- // TODO: should be warn !!
905
- return ''
906
- }
907
- };
848
+ };
908
849
 
909
- SingleElement.prototype.checkModified = function checkModified () {
910
- if (this._isBuiltIn) {
850
+ SingleElement.prototype.checkModified = function checkModified () {
911
851
  var el = this._vm.$el;
912
852
  if (el.tagName === 'SELECT') {
913
853
  return !looseEqual(this.initValue, getSelectValue(el))
@@ -918,25 +858,18 @@ SingleElement.prototype.checkModified = function checkModified () {
918
858
  return !looseEqual(this.initValue, el.value)
919
859
  }
920
860
  }
921
- } else if (this._isComponent) {
922
- return !looseEqual(this.initValue, this._vnode.child.value)
923
- } else {
924
- // TODO: should be warn !!
925
- return false
926
- }
927
- };
861
+ };
928
862
 
929
- SingleElement.prototype.listenToucheableEvent = function listenToucheableEvent () {
930
- this._vm.$el.addEventListener('focusout', this._vm.willUpdateTouched);
931
- };
863
+ SingleElement.prototype.listenToucheableEvent = function listenToucheableEvent () {
864
+ this._vm.$el.addEventListener('focusout', this._vm.willUpdateTouched);
865
+ };
932
866
 
933
- SingleElement.prototype.unlistenToucheableEvent = function unlistenToucheableEvent () {
934
- this._vm.$el.removeEventListener('focusout', this._vm.willUpdateTouched);
935
- };
867
+ SingleElement.prototype.unlistenToucheableEvent = function unlistenToucheableEvent () {
868
+ this._vm.$el.removeEventListener('focusout', this._vm.willUpdateTouched);
869
+ };
936
870
 
937
- SingleElement.prototype.listenInputableEvent = function listenInputableEvent () {
938
- var vm = this._vm;
939
- if (this._isBuiltIn) {
871
+ SingleElement.prototype.listenInputableEvent = function listenInputableEvent () {
872
+ var vm = this._vm;
940
873
  var el = vm.$el;
941
874
  if (el.tagName === 'SELECT') {
942
875
  el.addEventListener('change', vm.handleInputable);
@@ -947,16 +880,10 @@ SingleElement.prototype.listenInputableEvent = function listenInputableEvent ()
947
880
  el.addEventListener('input', vm.handleInputable);
948
881
  }
949
882
  }
950
- } else if (this._isComponent) {
951
- this._unwatchInputable = this._vnode.child.$watch('value', vm.watchInputable);
952
- } else {
953
- // TODO: should be warn !!
954
- }
955
- };
883
+ };
956
884
 
957
- SingleElement.prototype.unlistenInputableEvent = function unlistenInputableEvent () {
958
- var vm = this._vm;
959
- if (this._isBuiltIn) {
885
+ SingleElement.prototype.unlistenInputableEvent = function unlistenInputableEvent () {
886
+ var vm = this._vm;
960
887
  var el = vm.$el;
961
888
  if (el.tagName === 'SELECT') {
962
889
  el.removeEventListener('change', vm.handleInputable);
@@ -967,44 +894,11 @@ SingleElement.prototype.unlistenInputableEvent = function unlistenInputableEvent
967
894
  el.removeEventListener('input', vm.handleInputable);
968
895
  }
969
896
  }
970
- } else if (this._isComponent) {
971
- if (this._unwatchInputable) {
972
- this._unwatchInputable();
973
- this._unwatchInputable = undefined;
974
- delete this._unwatchInputable;
975
- }
976
- } else {
977
- // TODO: should be warn !!
978
- }
979
- };
980
-
981
- SingleElement.prototype.fireInputableEvent = function fireInputableEvent () {
982
- if (this._isBuiltIn) {
983
- var el = this._vm.$el;
984
- if (el.tagName === 'SELECT') {
985
- triggerEvent(el, 'change', addEventInfo);
986
- } else {
987
- if (el.type === 'checkbox') {
988
- triggerEvent(el, 'change', addEventInfo);
989
- } else {
990
- triggerEvent(el, 'input', addEventInfo);
991
- }
992
- }
993
- } else if (this._isComponent) {
994
- var args = { value: this.getValue() };
995
- args[MODEL_NOTIFY_EVENT] = 'COMPONENT';
996
- this._vnode.child.$emit('input', args);
997
- } else {
998
- // TODO: should be warn !!
999
- }
1000
- };
897
+ };
1001
898
 
1002
- SingleElement.prototype.modelValueEqual = function modelValueEqual$1 () {
1003
- return modelValueEqual(this._vnode)
899
+ return SingleElement
1004
900
  };
1005
901
 
1006
- Object.defineProperties( SingleElement.prototype, prototypeAccessors );
1007
-
1008
902
  function getSelectValue (el) {
1009
903
  var value = [];
1010
904
  for (var i = 0, l = el.options.length; i < l; i++) {
@@ -1017,105 +911,290 @@ function getSelectValue (el) {
1017
911
  }
1018
912
 
1019
913
  /* */
1020
- var MultiElement = function MultiElement (vm) {
1021
- // TODO: should be checked whether included radio or checkbox
1022
- this._vm = vm;
1023
- this.initValue = this.getValue();
1024
- this.attachValidity();
1025
- };
1026
914
 
1027
- MultiElement.prototype.attachValidity = function attachValidity () {
1028
- var this$1 = this;
915
+ var MultiElementClass = function (Vue) {
916
+ var ref = Vue.util;
917
+ var looseEqual = ref.looseEqual;
1029
918
 
1030
- this._vm.$el.$validity = this._vm;
1031
- this._eachItems(function (item) {
1032
- item.$validity = this$1._vm;
1033
- });
1034
- };
919
+ var MultiElement = function MultiElement (vm) {
920
+ // TODO: should be checked whether included radio or checkbox
921
+ this._vm = vm;
922
+ this.initValue = this.getValue();
923
+ this.attachValidity();
924
+ };
1035
925
 
1036
- MultiElement.prototype.getValue = function getValue () {
1037
- return this._getCheckedValue()
1038
- };
926
+ MultiElement.prototype.attachValidity = function attachValidity () {
927
+ var this$1 = this;
1039
928
 
1040
- MultiElement.prototype.checkModified = function checkModified () {
1041
- return !looseEqual(this.initValue, this._getCheckedValue())
1042
- };
929
+ this._vm.$el.$validity = this._vm;
930
+ this._eachItems(function (item) {
931
+ item.$validity = this$1._vm;
932
+ });
933
+ };
1043
934
 
1044
- MultiElement.prototype.listenToucheableEvent = function listenToucheableEvent () {
1045
- var this$1 = this;
935
+ MultiElement.prototype.getValue = function getValue () {
936
+ return this._getCheckedValue()
937
+ };
1046
938
 
1047
- this._eachItems(function (item) {
1048
- item.addEventListener('focusout', this$1._vm.willUpdateTouched);
1049
- });
1050
- };
939
+ MultiElement.prototype.checkModified = function checkModified () {
940
+ return !looseEqual(this.initValue, this._getCheckedValue())
941
+ };
1051
942
 
1052
- MultiElement.prototype.unlistenToucheableEvent = function unlistenToucheableEvent () {
1053
- var this$1 = this;
943
+ MultiElement.prototype.listenToucheableEvent = function listenToucheableEvent () {
944
+ var this$1 = this;
1054
945
 
1055
- this._eachItems(function (item) {
1056
- item.removeEventListener('focusout', this$1._vm.willUpdateTouched);
1057
- });
1058
- };
946
+ this._eachItems(function (item) {
947
+ item.addEventListener('focusout', this$1._vm.willUpdateTouched);
948
+ });
949
+ };
1059
950
 
1060
- MultiElement.prototype.listenInputableEvent = function listenInputableEvent () {
1061
- var this$1 = this;
951
+ MultiElement.prototype.unlistenToucheableEvent = function unlistenToucheableEvent () {
952
+ var this$1 = this;
1062
953
 
1063
- this._eachItems(function (item) {
1064
- item.addEventListener('change', this$1._vm.handleInputable);
1065
- });
1066
- };
954
+ this._eachItems(function (item) {
955
+ item.removeEventListener('focusout', this$1._vm.willUpdateTouched);
956
+ });
957
+ };
1067
958
 
1068
- MultiElement.prototype.unlistenInputableEvent = function unlistenInputableEvent () {
1069
- var this$1 = this;
959
+ MultiElement.prototype.listenInputableEvent = function listenInputableEvent () {
960
+ var this$1 = this;
1070
961
 
1071
- this._eachItems(function (item) {
1072
- item.removeEventListener('change', this$1._vm.handleInputable);
1073
- });
1074
- };
962
+ this._eachItems(function (item) {
963
+ item.addEventListener('change', this$1._vm.handleInputable);
964
+ });
965
+ };
1075
966
 
1076
- MultiElement.prototype.fireInputableEvent = function fireInputableEvent () {
1077
- this._eachItems(function (item) {
1078
- triggerEvent(item, 'change', addEventInfo);
1079
- });
967
+ MultiElement.prototype.unlistenInputableEvent = function unlistenInputableEvent () {
968
+ var this$1 = this;
969
+
970
+ this._eachItems(function (item) {
971
+ item.removeEventListener('change', this$1._vm.handleInputable);
972
+ });
973
+ };
974
+
975
+ MultiElement.prototype._getCheckedValue = function _getCheckedValue () {
976
+ var value = [];
977
+ this._eachItems(function (item) {
978
+ if (!item.disabled && item.checked) {
979
+ value.push(item.value);
980
+ }
981
+ });
982
+ return value
983
+ };
984
+
985
+ MultiElement.prototype._getItems = function _getItems () {
986
+ return this._vm.$el.querySelectorAll('input[type="checkbox"], input[type="radio"]')
987
+ };
988
+
989
+ MultiElement.prototype._eachItems = function _eachItems (cb) {
990
+ var items = this._getItems();
991
+ for (var i = 0; i < items.length; i++) {
992
+ cb(items[i]);
993
+ }
994
+ };
995
+
996
+ return MultiElement
1080
997
  };
1081
998
 
1082
- MultiElement.prototype.modelValueEqual = function modelValueEqual$1 () {
1083
- var ret = null;
1084
- var children = (this._vm.child && this._vm.child.children) || [];
1085
- for (var i = 0; i < children.length; i++) {
1086
- if (!modelValueEqual(children[i])) {
1087
- ret = false;
1088
- break
999
+ /* */
1000
+
1001
+ var inBrowser =
1002
+ typeof window !== 'undefined' &&
1003
+ Object.prototype.toString.call(window) !== '[object Object]';
1004
+ var UA = inBrowser && window.navigator.userAgent.toLowerCase();
1005
+ var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
1006
+
1007
+ function getClass (el) {
1008
+ var classname = el.className;
1009
+ if (typeof classname === 'object') {
1010
+ classname = classname.baseVal || '';
1011
+ }
1012
+ return classname
1013
+ }
1014
+
1015
+ function setClass (el, cls) {
1016
+ if (isIE9 && !/svg$/.test(el.namespaceURI)) {
1017
+ el.className = cls;
1018
+ } else {
1019
+ el.setAttribute('class', cls);
1020
+ }
1021
+ }
1022
+
1023
+ function addClass (el, cls) {
1024
+ if (el.classList) {
1025
+ el.classList.add(cls);
1026
+ } else {
1027
+ var cur = ' ' + getClass(el) + ' ';
1028
+ if (cur.indexOf(' ' + cls + ' ') < 0) {
1029
+ setClass(el, (cur + cls).trim());
1089
1030
  }
1090
1031
  }
1091
- return ret
1092
- };
1032
+ }
1093
1033
 
1094
- MultiElement.prototype._getCheckedValue = function _getCheckedValue () {
1095
- var value = [];
1096
- this._eachItems(function (item) {
1097
- if (!item.disabled && item.checked) {
1098
- value.push(item.value);
1034
+ function removeClass (el, cls) {
1035
+ if (el.classList) {
1036
+ el.classList.remove(cls);
1037
+ } else {
1038
+ var cur = ' ' + getClass(el) + ' ';
1039
+ var tar = ' ' + cls + ' ';
1040
+ while (cur.indexOf(tar) >= 0) {
1041
+ cur = cur.replace(tar, ' ');
1099
1042
  }
1100
- });
1101
- return value
1102
- };
1043
+ setClass(el, cur.trim());
1044
+ }
1045
+ if (!el.className) {
1046
+ el.removeAttribute('class');
1047
+ }
1048
+ }
1103
1049
 
1104
- MultiElement.prototype._getItems = function _getItems () {
1105
- return this._vm.$el.querySelectorAll('input[type="checkbox"], input[type="radio"]')
1106
- };
1050
+ function toggleClasses (el, key, fn) {
1051
+ if (!el) { return }
1052
+
1053
+ key = key.trim();
1054
+ if (key.indexOf(' ') === -1) {
1055
+ fn(el, key);
1056
+ return
1057
+ }
1107
1058
 
1108
- MultiElement.prototype._eachItems = function _eachItems (cb) {
1109
- var items = this._getItems();
1110
- for (var i = 0; i < items.length; i++) {
1111
- cb(items[i]);
1059
+ var keys = key.split(/\s+/);
1060
+ for (var i = 0, l = keys.length; i < l; i++) {
1061
+ fn(el, keys[i]);
1112
1062
  }
1063
+ }
1064
+
1065
+ function memoize (fn) {
1066
+ var cache = Object.create(null);
1067
+ return function memoizeFn (id) {
1068
+ var args = [], len = arguments.length - 1;
1069
+ while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
1070
+
1071
+ var hit = cache[id];
1072
+ return hit || (cache[id] = fn.apply(void 0, args))
1073
+ }
1074
+ }
1075
+
1076
+ /* */
1077
+ var ComponentElementClass = function (Vue) {
1078
+ var ref = Vue.util;
1079
+ var looseEqual = ref.looseEqual;
1080
+ var isPlainObject = ref.isPlainObject;
1081
+
1082
+ function getValidatorProps (validators) {
1083
+ var normalized = typeof validators === 'string' ? [validators] : validators;
1084
+ var targets = [];
1085
+ if (isPlainObject(normalized)) {
1086
+ Object.keys(normalized).forEach(function (validator) {
1087
+ var props = (normalized[validator] &&
1088
+ normalized[validator]['props'] &&
1089
+ isPlainObject(normalized[validator]['props']))
1090
+ ? normalized[validator]['props']
1091
+ : null;
1092
+ if (props) {
1093
+ Object.keys(props).forEach(function (prop) {
1094
+ if (!~targets.indexOf(prop)) {
1095
+ targets.push(prop);
1096
+ }
1097
+ });
1098
+ }
1099
+ });
1100
+ }
1101
+ return targets
1102
+ }
1103
+
1104
+ var ComponentElement = function ComponentElement (vm, vnode, validatorProps) {
1105
+ this._vm = vm;
1106
+ this._vnode = vnode;
1107
+ this._validatorProps = validatorProps || memoize(getValidatorProps);
1108
+ this.initValue = this.getValue();
1109
+ this._watchers = [];
1110
+ this.attachValidity();
1111
+ };
1112
+
1113
+ ComponentElement.prototype.attachValidity = function attachValidity () {
1114
+ this._vm.$el.$validity = this._vm;
1115
+ };
1116
+
1117
+ ComponentElement.prototype.getValidatorProps = function getValidatorProps$1 () {
1118
+ var vm = this._vm;
1119
+ return this._validatorProps(vm._uid.toString(), vm.validators)
1120
+ };
1121
+
1122
+ ComponentElement.prototype.getValue = function getValue () {
1123
+ var this$1 = this;
1124
+
1125
+ var value = {};
1126
+ this.getValidatorProps().forEach(function (prop) {
1127
+ value[prop] = this$1._vnode.child[prop];
1128
+ });
1129
+ return value
1130
+ };
1131
+
1132
+ ComponentElement.prototype.checkModified = function checkModified () {
1133
+ return !looseEqual(this.initValue, this.getValue())
1134
+ };
1135
+
1136
+ ComponentElement.prototype.listenToucheableEvent = function listenToucheableEvent () {
1137
+ this._vm.$el.addEventListener('focusout', this._vm.willUpdateTouched);
1138
+ };
1139
+
1140
+ ComponentElement.prototype.unlistenToucheableEvent = function unlistenToucheableEvent () {
1141
+ this._vm.$el.removeEventListener('focusout', this._vm.willUpdateTouched);
1142
+ };
1143
+
1144
+ ComponentElement.prototype.listenInputableEvent = function listenInputableEvent () {
1145
+ var this$1 = this;
1146
+
1147
+ this.getValidatorProps().forEach(function (prop) {
1148
+ this$1._watchers.push(this$1._vnode.child.$watch(prop, this$1._vm.watchInputable));
1149
+ });
1150
+ };
1151
+
1152
+ ComponentElement.prototype.unlistenInputableEvent = function unlistenInputableEvent () {
1153
+ this._watchers.forEach(function (watcher) { watcher(); });
1154
+ this._watchers = [];
1155
+ };
1156
+
1157
+ return ComponentElement
1113
1158
  };
1114
1159
 
1115
1160
  /* */
1161
+ var Elements = function (Vue) {
1162
+ var SingleElement = SingleElementClass(Vue);
1163
+ var MultiElement = MultiElementClass(Vue);
1164
+ var ComponentElement = ComponentElementClass(Vue);
1165
+
1166
+ return {
1167
+ SingleElement: SingleElement,
1168
+ MultiElement: MultiElement,
1169
+ ComponentElement: ComponentElement
1170
+ }
1171
+ };
1116
1172
 
1117
1173
  /* */
1118
1174
  var Lifecycles = function (Vue) {
1175
+ var ref = Elements(Vue);
1176
+ var SingleElement = ref.SingleElement;
1177
+ var MultiElement = ref.MultiElement;
1178
+ var ComponentElement = ref.ComponentElement;
1179
+
1180
+ function createValidityElement (vm, vnode) {
1181
+ return vm.multiple
1182
+ ? new MultiElement(vm)
1183
+ : checkBuiltInElement(vnode)
1184
+ ? new SingleElement(vm)
1185
+ : checkComponentElement(vnode)
1186
+ ? new ComponentElement(vm, vnode)
1187
+ : null
1188
+ }
1189
+
1190
+ function watchModelable (val) {
1191
+ this.$emit('input', {
1192
+ result: this.result,
1193
+ progress: this.progress,
1194
+ progresses: this.progresses
1195
+ });
1196
+ }
1197
+
1119
1198
  function created () {
1120
1199
  this._elementable = null;
1121
1200
 
@@ -1144,64 +1223,75 @@ var Lifecycles = function (Vue) {
1144
1223
  var instance = validation.instance;
1145
1224
  var name = validation.name;
1146
1225
  var group = this.group;
1147
- instance.unregister(this.field, this, { named: name, group: group });
1226
+ instance.unregister(this.field, { named: name, group: group });
1227
+ }
1228
+
1229
+ if (this._unwatchResultProp) {
1230
+ this._unwatchResultProp();
1231
+ this._unwatchResultProp = null;
1232
+ }
1233
+
1234
+ if (this._unwatchProgressProp) {
1235
+ this._unwatchProgressProp();
1236
+ this._unwatchProgressProp = null;
1148
1237
  }
1149
1238
 
1150
1239
  this._unwatchValidationRawResults();
1151
1240
 
1152
1241
  this._elementable.unlistenInputableEvent();
1153
- this._elementable.unlistenToucheableEvent();
1242
+ if (this.autotouch === 'on') {
1243
+ this._elementable.unlistenToucheableEvent();
1244
+ }
1154
1245
  this._elementable = null;
1155
1246
  }
1156
1247
 
1157
1248
  function mounted () {
1158
- this._elementable = createValidityElement(this);
1159
- this._elementable.listenToucheableEvent();
1160
- this._elementable.listenInputableEvent();
1249
+ this._elementable = createValidityElement(this, this._vnode);
1250
+ if (this._elementable) {
1251
+ if (this.autotouch === 'on') {
1252
+ this._elementable.listenToucheableEvent();
1253
+ }
1254
+ this._elementable.listenInputableEvent();
1255
+ } else {
1256
+ // TODO: should be warn
1257
+ }
1258
+
1259
+ if (hasModelDirective(this.$vnode)) {
1260
+ this._unwatchResultProp = this.$watch('result', watchModelable);
1261
+ this._unwatchProgressProp = this.$watch('progress', watchModelable);
1262
+ }
1161
1263
 
1162
1264
  toggleClasses(this.$el, this.classes.untouched, addClass);
1163
1265
  toggleClasses(this.$el, this.classes.pristine, addClass);
1164
1266
  }
1165
1267
 
1166
- function updated () {
1167
- var maybeChangeModel = this._elementable.modelValueEqual();
1168
- if (!this._applyWithUserHandler && maybeChangeModel !== null && !maybeChangeModel) {
1169
- this._elementable.fireInputableEvent();
1170
- }
1171
- delete this._applyWithUserHandler;
1172
- }
1173
-
1174
1268
  return {
1175
1269
  created: created,
1176
1270
  destroyed: destroyed,
1177
- mounted: mounted,
1178
- updated: updated
1271
+ mounted: mounted
1179
1272
  }
1180
1273
  };
1181
1274
 
1182
- function memoize (fn) {
1183
- var cache = Object.create(null);
1184
- return function memoizeFn (id) {
1185
- var args = [], len = arguments.length - 1;
1186
- while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
1275
+ function checkComponentElement (vnode) {
1276
+ return vnode.child &&
1277
+ vnode.componentOptions &&
1278
+ vnode.tag &&
1279
+ vnode.tag.match(/vue-component/)
1280
+ }
1187
1281
 
1188
- var hit = cache[id];
1189
- return hit || (cache[id] = fn.apply(void 0, args))
1190
- }
1282
+ function checkBuiltInElement (vnode) {
1283
+ return !vnode.child &&
1284
+ !vnode.componentOptions &&
1285
+ vnode.tag
1191
1286
  }
1192
1287
 
1193
- function createValidityElement (vm) {
1194
- var vnode = vm.child;
1195
- return !vm.multiple
1196
- ? new SingleElement(vm, vnode)
1197
- : new MultiElement(vm)
1288
+ function hasModelDirective (vnode) {
1289
+ return ((vnode && vnode.data && vnode.data.directives) || []).find(function (dir) { return dir.name === 'model'; })
1198
1290
  }
1199
1291
 
1200
1292
  /* */
1201
- var Event = function (Vue) {
1202
- var ref = Vue.util;
1203
- var toArray = ref.toArray;
1204
1293
 
1294
+ var Event = function (Vue) {
1205
1295
  function _fireEvent (type) {
1206
1296
  var args = [], len = arguments.length - 1;
1207
1297
  while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
@@ -1210,92 +1300,16 @@ var Event = function (Vue) {
1210
1300
  var ref;
1211
1301
  }
1212
1302
 
1213
- function _interceptEvents (child, multiple) {
1214
- var this$1 = this;
1215
-
1216
- (multiple ? (child.children || []) : [child]).forEach(function (child) { this$1._wrapEvent(child); });
1217
- }
1218
-
1219
- function _wrapEvent (child) {
1220
- var this$1 = this;
1221
-
1222
- var ret = {};
1223
- if (!child.tag || !child.data) { return ret }
1224
-
1225
- var dir = getModelDirective(child);
1226
- if (!dir) { return ret }
1227
-
1228
- var ref = getEventSources(child);
1229
- var type = ref.type;
1230
- var orgListeners = ref.orgListeners;
1231
- var listeners = ref.listeners;
1232
- if (!Array.isArray(orgListeners)) { return ret }
1233
-
1234
- var modelHandler = orgListeners[0];
1235
- var userHandler = orgListeners[1];
1236
- var modelApplyer = function (args) {
1237
- return function () {
1238
- this$1._applyWithUserHandler = true;
1239
- modelHandler.apply(child.context, args);
1240
- }
1241
- };
1242
- var modifier = (dir.modifiers || {}).validity;
1243
- listeners[type] = function () {
1244
- var args = toArray(arguments, 0);
1245
- var event = args[0];
1246
- if (event[MODEL_NOTIFY_EVENT] === 'DOM') {
1247
- delete event[MODEL_NOTIFY_EVENT];
1248
- userHandler.apply(child.context, args);
1249
- return
1250
- } else if (event[MODEL_NOTIFY_EVENT] === 'COMPONENT') {
1251
- var value = event.value;
1252
- args[0] = value;
1253
- userHandler.apply(child.context, args);
1254
- return
1255
- }
1256
-
1257
- if (modifier) {
1258
- args.push(modelApplyer(args));
1259
- userHandler.apply(child.context, args);
1260
- } else {
1261
- userHandler.apply(child.context, args);
1262
- modelHandler.apply(child.context, args);
1263
- }
1264
- };
1265
-
1266
- ret.dir = dir;
1267
- return ret
1268
- }
1269
-
1270
1303
  return {
1271
- _fireEvent: _fireEvent,
1272
- _interceptEvents: _interceptEvents,
1273
- _wrapEvent: _wrapEvent
1304
+ _fireEvent: _fireEvent
1274
1305
  }
1275
1306
  };
1276
1307
 
1277
- function getModelDirective (child) {
1278
- return ((child.data && child.data.directives) || []).find(function (dir) { return dir.name === 'model' })
1279
- }
1280
-
1281
- function getEventSources (child) {
1282
- var sources = {};
1283
- var listeners = sources.listeners = child.componentOptions
1284
- ? child.componentOptions.listeners
1285
- : (child.data && child.data.on);
1286
- sources.type =
1287
- (child.tag === 'input' && (child.data && child.data.attrs && child.data.attrs.type) === 'text') ||
1288
- (child.tag && child.tag.match(/vue-component/))
1289
- ? 'input'
1290
- : 'change';
1291
- if (listeners) {
1292
- sources.orgListeners = listeners[sources.type];
1293
- }
1294
- return sources
1295
- }
1296
-
1297
1308
  /* */
1298
1309
  var State = function (Vue) {
1310
+ var ref = Vue.util;
1311
+ var isPlainObject = ref.isPlainObject;
1312
+
1299
1313
  function getValue (options) {
1300
1314
  return this._elementable.getValue()
1301
1315
  }
@@ -1341,15 +1355,25 @@ var State = function (Vue) {
1341
1355
  this.willUpdateModified();
1342
1356
  }
1343
1357
 
1344
- function reset () {
1345
- var this$1 = this;
1358
+ function _initStates (keys, target, init) {
1359
+ if ( init === void 0 ) init = undefined;
1346
1360
 
1347
- this._unwatchValidationRawResults();
1348
- var keys = this._keysCached(this._uid.toString(), this.results);
1349
1361
  for (var i = 0; i < keys.length; i++) {
1350
- this$1.results[keys[i]] = undefined;
1351
- this$1.progresses[keys[i]] = '';
1362
+ var result = target[keys[i]];
1363
+ if (isPlainObject(result)) {
1364
+ var nestedKeys = Object.keys(result);
1365
+ _initStates(nestedKeys, result, init);
1366
+ } else {
1367
+ target[keys[i]] = init;
1368
+ }
1352
1369
  }
1370
+ }
1371
+
1372
+ function reset () {
1373
+ this._unwatchValidationRawResults();
1374
+ var keys = this._keysCached(this._uid.toString(), this.results);
1375
+ _initStates(keys, this.results, undefined);
1376
+ _initStates(keys, this.progresses, '');
1353
1377
  toggleClasses(this.$el, this.classes.valid, removeClass);
1354
1378
  toggleClasses(this.$el, this.classes.invalid, removeClass);
1355
1379
  toggleClasses(this.$el, this.classes.touched, removeClass);
@@ -1365,26 +1389,38 @@ var State = function (Vue) {
1365
1389
  this._watchValidationRawResults();
1366
1390
  }
1367
1391
 
1368
- function _watchValidationRawResults () {
1369
- var this$1 = this;
1370
-
1371
- this._unwatch = this.$watch('results', function (val) {
1372
- var valid = true;
1373
- var keys = this$1._keysCached(this$1._uid.toString(), this$1.results);
1374
- for (var i = 0; i < keys.length; i++) {
1375
- var result = this$1.results[keys[i]];
1376
- if (typeof result === 'boolean' && !result) {
1377
- valid = false;
1378
- break
1379
- }
1380
- if (typeof result === 'string' && result) {
1381
- valid = false;
1392
+ function _walkValid (keys, target) {
1393
+ var valid = true;
1394
+ for (var i = 0; i < keys.length; i++) {
1395
+ var result = target[keys[i]];
1396
+ if (typeof result === 'boolean' && !result) {
1397
+ valid = false;
1398
+ break
1399
+ }
1400
+ if (typeof result === 'string' && result) {
1401
+ valid = false;
1402
+ break
1403
+ }
1404
+ if (isPlainObject(result)) {
1405
+ var nestedKeys = Object.keys(result);
1406
+ valid = _walkValid(nestedKeys, result);
1407
+ if (!valid) {
1382
1408
  break
1383
1409
  }
1384
1410
  }
1385
- this$1.valid = valid;
1411
+ }
1412
+ return valid
1413
+ }
1414
+
1415
+ function _watchValidationRawResults () {
1416
+ var this$1 = this;
1386
1417
 
1387
- if (valid) {
1418
+ this._unwatchResults = this.$watch('results', function (val) {
1419
+ this$1.valid = _walkValid(
1420
+ this$1._keysCached(this$1._uid.toString(), this$1.results),
1421
+ this$1.results
1422
+ );
1423
+ if (this$1.valid) {
1388
1424
  toggleClasses(this$1.$el, this$1.classes.valid, addClass);
1389
1425
  toggleClasses(this$1.$el, this$1.classes.invalid, removeClass);
1390
1426
  } else {
@@ -1392,14 +1428,18 @@ var State = function (Vue) {
1392
1428
  toggleClasses(this$1.$el, this$1.classes.invalid, addClass);
1393
1429
  }
1394
1430
 
1395
- this$1._fireEvent(valid ? 'valid' : 'invalid');
1431
+ this$1._fireEvent(this$1.valid ? 'valid' : 'invalid');
1396
1432
  }, { deep: true });
1397
1433
  }
1398
1434
 
1399
1435
  function _unwatchValidationRawResults () {
1400
- this._unwatch();
1401
- this._unwatch = undefined;
1402
- delete this._unwatch;
1436
+ this._unwatchResults();
1437
+ this._unwatchResults = undefined;
1438
+ delete this._unwatchResults;
1439
+ }
1440
+
1441
+ function touch () {
1442
+ this.willUpdateTouched();
1403
1443
  }
1404
1444
 
1405
1445
  return {
@@ -1411,8 +1451,10 @@ var State = function (Vue) {
1411
1451
  handleInputable: handleInputable,
1412
1452
  watchInputable: watchInputable,
1413
1453
  reset: reset,
1454
+ _walkValid: _walkValid,
1414
1455
  _watchValidationRawResults: _watchValidationRawResults,
1415
- _unwatchValidationRawResults: _unwatchValidationRawResults
1456
+ _unwatchValidationRawResults: _unwatchValidationRawResults,
1457
+ touch: touch
1416
1458
  }
1417
1459
  };
1418
1460
 
@@ -1426,23 +1468,23 @@ function isPromise (p) {
1426
1468
  }
1427
1469
 
1428
1470
  var Validate = function (Vue) {
1471
+ var ref = Vue.util;
1472
+ var extend = ref.extend;
1473
+ var isPlainObject = ref.isPlainObject;
1474
+ var resolveAsset = ref.resolveAsset;
1475
+
1429
1476
  function _resolveValidator (name) {
1430
- var ref = Vue.util;
1431
- var resolveAsset = ref.resolveAsset;
1432
1477
  var options = (this.child && this.child.context)
1433
1478
  ? this.child.context.$options
1434
1479
  : this.$options;
1435
1480
  return resolveAsset(options, 'validators', name)
1436
1481
  }
1437
1482
 
1438
- function _getValidateDescriptor (
1483
+ function _getValidateRawDescriptor (
1439
1484
  validator,
1440
1485
  field,
1441
1486
  value
1442
1487
  ) {
1443
- var ref = Vue.util;
1444
- var isPlainObject = ref.isPlainObject;
1445
-
1446
1488
  var asset = this._resolveValidator(validator);
1447
1489
  if (!asset) {
1448
1490
  // TODO: should be warned
@@ -1471,16 +1513,22 @@ var Validate = function (Vue) {
1471
1513
  return null
1472
1514
  }
1473
1515
 
1474
- if (isPlainObject(this.validators)) {
1475
- if (isPlainObject(this.validators[validator])) {
1476
- if (this.validators[validator].rule) {
1477
- rule = this.validators[validator].rule;
1478
- }
1479
- if (this.validators[validator].message) {
1480
- msg = this.validators[validator].message;
1516
+ var props = null;
1517
+ var validators = this.validators;
1518
+ if (isPlainObject(validators)) {
1519
+ if (isPlainObject(validators[validator])) {
1520
+ if (validators[validator].props && isPlainObject(validators[validator].props)) {
1521
+ props = validators[validator].props;
1522
+ } else {
1523
+ if (validators[validator].rule) {
1524
+ rule = validators[validator].rule;
1525
+ }
1526
+ if (validators[validator].message) {
1527
+ msg = validators[validator].message;
1528
+ }
1481
1529
  }
1482
1530
  } else {
1483
- rule = this.validators[validator];
1531
+ rule = validators[validator];
1484
1532
  }
1485
1533
  }
1486
1534
 
@@ -1491,6 +1539,9 @@ var Validate = function (Vue) {
1491
1539
  if (msg) {
1492
1540
  descriptor.msg = msg;
1493
1541
  }
1542
+ if (props) {
1543
+ descriptor.props = props;
1544
+ }
1494
1545
 
1495
1546
  return descriptor
1496
1547
  }
@@ -1510,16 +1561,16 @@ var Validate = function (Vue) {
1510
1561
 
1511
1562
  function _invokeValidator (
1512
1563
  ref,
1564
+ value,
1513
1565
  cb
1514
1566
  ) {
1515
1567
  var this$1 = this;
1516
1568
  var fn = ref.fn;
1517
- var value = ref.value;
1518
1569
  var field = ref.field;
1519
1570
  var rule = ref.rule;
1520
1571
  var msg = ref.msg;
1521
1572
 
1522
- var future = fn.call(this, value, rule);
1573
+ var future = fn.call(this.child.context, value, rule);
1523
1574
  if (typeof future === 'function') { // function
1524
1575
  future(function () { // resolve
1525
1576
  cb(true);
@@ -1539,15 +1590,103 @@ var Validate = function (Vue) {
1539
1590
  }
1540
1591
  }
1541
1592
 
1593
+ function _getValidateDescriptors (
1594
+ validator,
1595
+ field,
1596
+ value
1597
+ ) {
1598
+ var descriptors = [];
1599
+
1600
+ var rawDescriptor = this._getValidateRawDescriptor(validator, this.field, value);
1601
+ if (!rawDescriptor) { return descriptors }
1602
+
1603
+ if (!rawDescriptor.props) {
1604
+ var descriptor = { name: validator };
1605
+ extend(descriptor, rawDescriptor);
1606
+ descriptors.push(descriptor);
1607
+ } else {
1608
+ var propsKeys = Object.keys(!rawDescriptor.props);
1609
+ propsKeys.forEach(function (prop) {
1610
+ var descriptor = {
1611
+ fn: rawDescriptor.fn,
1612
+ name: validator,
1613
+ value: rawDescriptor.value[prop],
1614
+ field: rawDescriptor.field,
1615
+ prop: prop
1616
+ };
1617
+ if (rawDescriptor.props[prop].rule) {
1618
+ descriptor.rule = rawDescriptor.props[prop].rule;
1619
+ }
1620
+ if (rawDescriptor.props[prop].message) {
1621
+ descriptor.msg = rawDescriptor.props[prop].message;
1622
+ }
1623
+ descriptors.push(descriptor);
1624
+ });
1625
+ }
1626
+
1627
+ return descriptors
1628
+ }
1629
+
1630
+ function _syncValidates (field, cb) {
1631
+ var this$1 = this;
1632
+
1633
+ var validators = this._keysCached(this._uid.toString(), this.results);
1634
+ var value = this.getValue();
1635
+ var descriptors = [];
1636
+ validators.forEach(function (validator) {
1637
+ this$1._getValidateDescriptors(validator, field, value).forEach(function (desc) {
1638
+ descriptors.push(desc);
1639
+ });
1640
+ });
1641
+
1642
+ var count = 0;
1643
+ var len = descriptors.length;
1644
+ descriptors.forEach(function (desc) {
1645
+ var validator = desc.name;
1646
+ var prop = desc.prop;
1647
+ if ((!prop && this$1.progresses[validator]) || (prop && this$1.progresses[validator][prop])) {
1648
+ count++;
1649
+ if (count === len) {
1650
+ cb(this$1._walkValid(this$1._keysCached(this$1._uid.toString(), this$1.results), this$1.results));
1651
+ }
1652
+ return
1653
+ }
1654
+
1655
+ if (!prop) {
1656
+ this$1.progresses[validator] = 'running';
1657
+ } else {
1658
+ this$1.progresses[validator][prop] = 'running';
1659
+ }
1660
+
1661
+ this$1.$nextTick(function () {
1662
+ this$1._invokeValidator(desc, desc.value, function (ret, msg) {
1663
+ if (!prop) {
1664
+ this$1.progresses[validator] = '';
1665
+ this$1.results[validator] = msg || ret;
1666
+ } else {
1667
+ this$1.progresses[validator][prop] = '';
1668
+ this$1.results[validator][prop] = msg || ret;
1669
+ }
1670
+
1671
+ count++;
1672
+ if (count === len) {
1673
+ cb(this$1._walkValid(this$1._keysCached(this$1._uid.toString(), this$1.results), this$1.results));
1674
+ }
1675
+ });
1676
+ });
1677
+ });
1678
+ }
1679
+
1680
+ // TODO:should be refactor!!
1542
1681
  function _validate (validator, value, cb) {
1543
1682
  var this$1 = this;
1544
1683
 
1545
- var descriptor = this._getValidateDescriptor(validator, this.field, value);
1546
- if (descriptor) {
1684
+ var descriptor = this._getValidateRawDescriptor(validator, this.field, value);
1685
+ if (descriptor && !descriptor.props) {
1547
1686
  if (this.progresses[validator]) { return false }
1548
1687
  this.progresses[validator] = 'running';
1549
1688
  this.$nextTick(function () {
1550
- this$1._invokeValidator(descriptor, function (ret, msg) {
1689
+ this$1._invokeValidator(descriptor, descriptor.value, function (ret, msg) {
1551
1690
  this$1.progresses[validator] = '';
1552
1691
  this$1.results[validator] = msg || ret;
1553
1692
  if (cb) {
@@ -1563,6 +1702,35 @@ var Validate = function (Vue) {
1563
1702
  }
1564
1703
  });
1565
1704
  });
1705
+ } else if (descriptor && descriptor.props) {
1706
+ var propsKeys = Object.keys(descriptor.props);
1707
+ propsKeys.forEach(function (prop) {
1708
+ if (this$1.progresses[validator][prop]) { return }
1709
+ this$1.progresses[validator][prop] = 'running';
1710
+ var values = descriptor.value;
1711
+ var propDescriptor = {
1712
+ fn: descriptor.fn,
1713
+ value: values[prop],
1714
+ field: descriptor.field
1715
+ };
1716
+ if (descriptor.props[prop].rule) {
1717
+ propDescriptor.rule = descriptor.props[prop].rule;
1718
+ }
1719
+ if (descriptor.props[prop].message) {
1720
+ propDescriptor.msg = descriptor.props[prop].message;
1721
+ }
1722
+ this$1.$nextTick(function () {
1723
+ this$1._invokeValidator(propDescriptor, propDescriptor.value, function (result, msg) {
1724
+ this$1.progresses[validator][prop] = '';
1725
+ this$1.results[validator][prop] = msg || result;
1726
+ var e = { prop: prop, result: result };
1727
+ if (msg) {
1728
+ e['msg'] = msg;
1729
+ }
1730
+ this$1._fireEvent('validate', validator, e);
1731
+ });
1732
+ });
1733
+ });
1566
1734
  } else {
1567
1735
  // TODO:
1568
1736
  var err = new Error();
@@ -1571,6 +1739,7 @@ var Validate = function (Vue) {
1571
1739
  return true
1572
1740
  }
1573
1741
 
1742
+ // TODO: should be re-design of API
1574
1743
  function validate () {
1575
1744
  var this$1 = this;
1576
1745
  var args = [], len = arguments.length;
@@ -1586,9 +1755,15 @@ var Validate = function (Vue) {
1586
1755
  value = args[1];
1587
1756
  cb = args[2];
1588
1757
  } else if (args.length === 2) {
1589
- validators = this._keysCached(this._uid.toString(), this.results);
1590
- value = args[0];
1591
- cb = args[1];
1758
+ if (isPlainObject(args[0])) {
1759
+ validators = [args[0].validator];
1760
+ value = args[0].value || this.getValue();
1761
+ cb = args[1];
1762
+ } else {
1763
+ validators = this._keysCached(this._uid.toString(), this.results);
1764
+ value = args[0];
1765
+ cb = args[1];
1766
+ }
1592
1767
  } else if (args.length === 1) {
1593
1768
  validators = this._keysCached(this._uid.toString(), this.results);
1594
1769
  value = this.getValue();
@@ -1599,7 +1774,7 @@ var Validate = function (Vue) {
1599
1774
  cb = null;
1600
1775
  }
1601
1776
 
1602
- if (args.length === 3) {
1777
+ if (args.length === 3 || (args.length === 2 && isPlainObject(args[0]))) {
1603
1778
  ret = this._validate(validators[0], value, cb);
1604
1779
  } else {
1605
1780
  validators.forEach(function (validator) {
@@ -1612,10 +1787,12 @@ var Validate = function (Vue) {
1612
1787
 
1613
1788
  return {
1614
1789
  _resolveValidator: _resolveValidator,
1615
- _getValidateDescriptor: _getValidateDescriptor,
1790
+ _getValidateRawDescriptor: _getValidateRawDescriptor,
1791
+ _getValidateDescriptors: _getValidateDescriptors,
1616
1792
  _resolveMessage: _resolveMessage,
1617
1793
  _invokeValidator: _invokeValidator,
1618
1794
  _validate: _validate,
1795
+ _syncValidates: _syncValidates,
1619
1796
  validate: validate
1620
1797
  }
1621
1798
  };
@@ -1681,7 +1858,8 @@ var Validity = function (Vue) {
1681
1858
  if (!child.tag) { return child }
1682
1859
  var newData = extend({}, data);
1683
1860
  newData.props = extend({}, props);
1684
- extend(newData.props.classes, Vue.config.validator.classes);
1861
+ // TODO: should be refactored
1862
+ newData.props.classes = extend(extend(extend({}, DEFAULT_CLASSES), Vue.config.validator.classes), newData.props.classes);
1685
1863
  newData.props.child = child;
1686
1864
  return h('validity-control', newData)
1687
1865
  })
@@ -1715,7 +1893,8 @@ var ValidityGroup = function (Vue) {
1715
1893
  var child = h(props.tag, children);
1716
1894
  var newData = extend({}, data);
1717
1895
  newData.props = extend({}, props);
1718
- extend(newData.props.classes, Vue.config.validator.classes);
1896
+ // TODO: should be refactored
1897
+ newData.props.classes = extend(extend(extend({}, DEFAULT_CLASSES), Vue.config.validator.classes), newData.props.classes);
1719
1898
  newData.props.child = child;
1720
1899
  newData.props.multiple = true;
1721
1900
  return h('validity-control', newData)
@@ -1726,6 +1905,9 @@ var ValidityGroup = function (Vue) {
1726
1905
  /* */
1727
1906
 
1728
1907
  var Validation = function (Vue) {
1908
+ var ref = Vue.util;
1909
+ var extend = ref.extend;
1910
+
1729
1911
  return {
1730
1912
  functional: true,
1731
1913
  props: {
@@ -1753,7 +1935,11 @@ var Validation = function (Vue) {
1753
1935
  }
1754
1936
  var tag = props.tag || 'form';
1755
1937
  walkChildren(parent._validation, props.name, children);
1756
- return h(tag, tag === 'form' ? { attrs: { novalidate: true }} : {}, children)
1938
+ var newData = extend({ attrs: {}}, data);
1939
+ if (tag === 'form') {
1940
+ newData.attrs.novalidate = true;
1941
+ }
1942
+ return h(tag, newData, children)
1757
1943
  }
1758
1944
  }
1759
1945
  };
@@ -1782,6 +1968,46 @@ var Component = function (Vue) {
1782
1968
  }
1783
1969
  };
1784
1970
 
1971
+ /* */
1972
+ // TODO: should be defined strict type
1973
+ function mapValidation (results) {
1974
+ var res = {};
1975
+
1976
+ normalizeMap(results).forEach(function (ref) {
1977
+ var key = ref.key;
1978
+ var val = ref.val;
1979
+
1980
+ res[key] = function mappedValidation () {
1981
+ var validation = this.$validation;
1982
+ if (!this._isMounted) {
1983
+ return null
1984
+ }
1985
+ var paths = val.split('.');
1986
+ var first = paths.shift();
1987
+ if (first !== '$validation') {
1988
+ warn(("unknown validation result path: " + val));
1989
+ return null
1990
+ }
1991
+ var path;
1992
+ var value = validation;
1993
+ do {
1994
+ path = paths.shift();
1995
+ value = value[path];
1996
+ } while (paths.length > 0 && value !== undefined)
1997
+ return value
1998
+ };
1999
+ });
2000
+
2001
+ return res
2002
+ }
2003
+
2004
+ // TODO: should be defined strict type
2005
+ function normalizeMap (map) {
2006
+ return Array.isArray(map)
2007
+ ? map.map(function (key) { return ({ key: key, val: key }); })
2008
+ : Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); })
2009
+ }
2010
+
1785
2011
  /* */
1786
2012
  var installed = false;
1787
2013
 
@@ -1812,7 +2038,7 @@ function installComponent (Vue) {
1812
2038
  }
1813
2039
 
1814
2040
  plugin.mapValidation = mapValidation; // for standalone
1815
- plugin.version = '3.0.0-alpha.1';
2041
+ plugin.version = '3.0.0-alpha.2';
1816
2042
 
1817
2043
  if (typeof window !== 'undefined' && window.Vue) {
1818
2044
  window.Vue.use(plugin);