vuejs 1.0.35 → 1.0.36

Sign up to get free protection for your applications and to get access to all the features.
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);