vueonrails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +70 -0
  3. data/app/controllers/vue_controller.rb +2 -0
  4. data/app/helpers/syntax_helper.rb +28 -0
  5. data/app/views/vue/index.html.erb +1 -0
  6. data/config/routes.rb +5 -0
  7. data/lib/generators/generator_templates/packs/index.css +4 -0
  8. data/lib/generators/generator_templates/packs/index.js +30 -0
  9. data/lib/generators/generator_templates/packs/index.vue +13 -0
  10. data/lib/generators/generator_templates/packs/pack.js.erb +18 -0
  11. data/lib/generators/generator_templates/sfc/single-file-component.vue +45 -0
  12. data/lib/generators/generator_templates/tests/unit.test.js.erb +17 -0
  13. data/lib/generators/generator_templates/turbolinks/turbolinks-pack.js.erb +23 -0
  14. data/lib/generators/options/click.rb +10 -0
  15. data/lib/generators/options/form.rb +19 -0
  16. data/lib/generators/options/list.rb +32 -0
  17. data/lib/generators/options/modal.rb +26 -0
  18. data/lib/generators/options/seperate.rb +5 -0
  19. data/lib/generators/options/single.rb +3 -0
  20. data/lib/generators/options/table.rb +10 -0
  21. data/lib/generators/options/test.rb +2 -0
  22. data/lib/generators/options/turbolinks-seperate.rb +5 -0
  23. data/lib/generators/options/turbolinks-single.rb +3 -0
  24. data/lib/generators/options/vuex.rb +10 -0
  25. data/lib/generators/vue/USAGE +17 -0
  26. data/lib/generators/vue/vue_generator.rb +60 -0
  27. data/lib/install/Procfile +2 -0
  28. data/lib/install/config/alias.js +9 -0
  29. data/lib/install/setup.rb +78 -0
  30. data/lib/install/spv.rb +20 -0
  31. data/lib/install/test.rb +46 -0
  32. data/lib/install/turbolinks.rb +3 -0
  33. data/lib/install/ui.rb +4 -0
  34. data/lib/install/vuex.rb +12 -0
  35. data/lib/tasks/assets.rake +12 -0
  36. data/lib/tasks/info.rake +21 -0
  37. data/lib/tasks/vue.rake +27 -0
  38. data/lib/vueonrails.rb +13 -0
  39. data/lib/vueonrails/post_message.rb +4 -0
  40. data/lib/vueonrails/version.rb +3 -0
  41. data/vendor/assets/javascripts/axios.js +1545 -0
  42. data/vendor/assets/javascripts/axios.map +1 -0
  43. data/vendor/assets/javascripts/element-ui.js +12 -0
  44. data/vendor/assets/javascripts/vue-resource.js +1531 -0
  45. data/vendor/assets/javascripts/vue-router.js +2709 -0
  46. data/vendor/assets/javascripts/vue-router2.js +2284 -0
  47. data/vendor/assets/javascripts/vue-validator.js +910 -0
  48. data/vendor/assets/javascripts/vue-validator2.js +2615 -0
  49. data/vendor/assets/javascripts/vue-validator3.js +2054 -0
  50. data/vendor/assets/javascripts/vue.js +10237 -0
  51. data/vendor/assets/javascripts/vue.min.js +9 -0
  52. data/vendor/assets/javascripts/vue2.js +8568 -0
  53. data/vendor/assets/javascripts/vue2.min.js +8 -0
  54. data/vendor/assets/javascripts/vueonrails.js +39 -0
  55. data/vendor/assets/javascripts/vuex.js +722 -0
  56. data/vendor/assets/javascripts/vuex2.js +805 -0
  57. data/vendor/assets/stylesheets/element-ui.css +1 -0
  58. metadata +128 -0
@@ -0,0 +1,910 @@
1
+ /**
2
+ * vue-validator v1.4.4
3
+ * (c) 2014-2015 kazuya kawaguchi
4
+ * Released under the MIT License.
5
+ */
6
+
7
+ (function webpackUniversalModuleDefinition(root, factory) {
8
+ if(typeof exports === 'object' && typeof module === 'object')
9
+ module.exports = factory();
10
+ else if(typeof define === 'function' && define.amd)
11
+ define([], factory);
12
+ else if(typeof exports === 'object')
13
+ exports["vue-validator"] = factory();
14
+ else
15
+ root["vue-validator"] = factory();
16
+ })(this, function() {
17
+ return /******/ (function(modules) { // webpackBootstrap
18
+ /******/ // The module cache
19
+ /******/ var installedModules = {};
20
+
21
+ /******/ // The require function
22
+ /******/ function __webpack_require__(moduleId) {
23
+
24
+ /******/ // Check if module is in cache
25
+ /******/ if(installedModules[moduleId])
26
+ /******/ return installedModules[moduleId].exports;
27
+
28
+ /******/ // Create a new module (and put it into the cache)
29
+ /******/ var module = installedModules[moduleId] = {
30
+ /******/ exports: {},
31
+ /******/ id: moduleId,
32
+ /******/ loaded: false
33
+ /******/ };
34
+
35
+ /******/ // Execute the module function
36
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
37
+
38
+ /******/ // Flag the module as loaded
39
+ /******/ module.loaded = true;
40
+
41
+ /******/ // Return the exports of the module
42
+ /******/ return module.exports;
43
+ /******/ }
44
+
45
+
46
+ /******/ // expose the modules object (__webpack_modules__)
47
+ /******/ __webpack_require__.m = modules;
48
+
49
+ /******/ // expose the module cache
50
+ /******/ __webpack_require__.c = installedModules;
51
+
52
+ /******/ // __webpack_public_path__
53
+ /******/ __webpack_require__.p = "";
54
+
55
+ /******/ // Load entry module and return exports
56
+ /******/ return __webpack_require__(0);
57
+ /******/ })
58
+ /************************************************************************/
59
+ /******/ ([
60
+ /* 0 */
61
+ /***/ function(module, exports, __webpack_require__) {
62
+
63
+ /**
64
+ * Import(s)
65
+ */
66
+
67
+ var validates = __webpack_require__(1)
68
+ var _ = __webpack_require__(2)
69
+
70
+
71
+ /**
72
+ * Export(s)
73
+ */
74
+
75
+ module.exports = install
76
+
77
+
78
+ /**
79
+ * Install plugin
80
+ */
81
+
82
+ function install (Vue, options) {
83
+ options = options || {}
84
+ var componentName = options.component = options.component || '$validator'
85
+ var directiveName = options.directive = options.directive || 'validate'
86
+ var path = Vue.parsers.path
87
+ var util = Vue.util
88
+
89
+
90
+ // custom validators merge strategy setting
91
+ Vue.config.optionMergeStrategies.validator = function (parent, child, vm, k) {
92
+ var validatorOptions = { validates: {}, namespace: {} }
93
+ if (!parent && !child) {
94
+ return validatorOptions
95
+ } else if (!parent && child) {
96
+ util.extend(validatorOptions['validates'], child['validates'])
97
+ util.extend(validatorOptions['namespace'], child['namespace'])
98
+ return validatorOptions
99
+ } else if (parent && !child) {
100
+ util.extend(validatorOptions['validates'], parent['validates'])
101
+ util.extend(validatorOptions['namespace'], parent['namespace'])
102
+ return validatorOptions
103
+ } else if (parent && child) {
104
+ var key
105
+ if ('validates' in parent) {
106
+ util.extend(validatorOptions['validates'], parent['validates'])
107
+ }
108
+ if ('namespace' in parent) {
109
+ util.extend(validatorOptions['namespace'], parent['namespace'])
110
+ }
111
+ if ('validates' in child) {
112
+ for (key in child['validates']) {
113
+ if ('validates' in parent && !parent['validates'].hasOwnProperty(key)) {
114
+ validatorOptions['validates'][key] = child['validates'][key]
115
+ }
116
+ }
117
+ }
118
+ if ('namespace' in child) {
119
+ for (key in child['namespace']) {
120
+ if ('namespace' in parent && !parent['namespace'].hasOwnProperty(key)) {
121
+ validatorOptions['namespace'][key] = child['namespace'][key]
122
+ }
123
+ }
124
+ }
125
+ return validatorOptions
126
+ } else {
127
+ _.warn('unexpected validator option merge strategy')
128
+ return validatorOptions
129
+ }
130
+ }
131
+
132
+
133
+ function getVal (obj, keypath) {
134
+ var ret = null
135
+ try {
136
+ ret = path.get(obj, keypath)
137
+ } catch (e) { }
138
+ return ret
139
+ }
140
+
141
+
142
+ Vue.directive(directiveName, {
143
+
144
+ priority: 1024,
145
+
146
+ bind: function () {
147
+ var vm = this.vm
148
+ var el = this.el
149
+ var $validator = vm[componentName]
150
+ var keypath = this._keypath = this._parseModelAttribute(el.getAttribute(Vue.config.prefix + 'model'))
151
+ var validator = this.arg ? this.arg : this.expression
152
+ var arg = this.arg ? this.expression : null
153
+
154
+ var customs = _.getCustomValidators(vm.$options)
155
+ if (!this._checkValidator(validator, validates, customs)) {
156
+ _.warn("specified invalid '"
157
+ + validator + "' validator at v-validate directive !! please check '"
158
+ + validator + "' validator !!")
159
+ this._ignore = true
160
+ return
161
+ }
162
+
163
+ if (!$validator) {
164
+ vm[componentName] = $validator = vm.$addChild(
165
+ {}, // null option
166
+ Vue.extend(__webpack_require__(3))
167
+ )
168
+ }
169
+
170
+ var value = el.getAttribute('value')
171
+ if (el.getAttribute('number') !== null) {
172
+ value = util.toNumber(value)
173
+ }
174
+ this._init = value
175
+
176
+ var validation = $validator._getValidationNamespace('validation')
177
+ var init = value || vm.$get(keypath)
178
+ var readyEvent = el.getAttribute('wait-for')
179
+
180
+ if (readyEvent && !$validator._isRegistedReadyEvent(keypath)) {
181
+ $validator._addReadyEvents(keypath, this._checkParam('wait-for'))
182
+ }
183
+
184
+ this._setupValidator($validator, keypath, validation, validator, el, arg, init)
185
+ },
186
+
187
+ update: function (val, old) {
188
+ if (this._ignore) { return }
189
+
190
+ var self = this
191
+ var vm = this.vm
192
+ var keypath = this._keypath
193
+ var validator = this.arg ? this.arg : this.expression
194
+ var $validator = vm[componentName]
195
+
196
+ $validator._changeValidator(keypath, validator, val)
197
+ if (!$validator._isRegistedReadyEvent(keypath)) { // normal
198
+ this._updateValidator($validator, validator, keypath)
199
+ } else { // wait-for
200
+ vm.$once($validator._getReadyEvents(keypath), function (val) {
201
+ $validator._setInitialValue(keypath, val)
202
+ vm.$set(keypath, val)
203
+ self._updateValidator($validator, validator, keypath)
204
+ })
205
+ }
206
+ },
207
+
208
+
209
+ unbind: function () {
210
+ if (this._ignore) { return }
211
+
212
+ var vm = this.vm
213
+ var keypath = this._keypath
214
+ var validator = this.arg ? this.arg : this.expression
215
+ var $validator = vm[componentName]
216
+
217
+ this._teardownValidator(vm, $validator, keypath, validator)
218
+ },
219
+
220
+ _parseModelAttribute: function (attr) {
221
+ var res = Vue.parsers.directive.parse(attr)
222
+ return res[0].arg ? res[0].arg : res[0].expression
223
+ },
224
+
225
+ _checkValidator: function (validator, validates, customs) {
226
+ var items = Object.keys(validates).concat(Object.keys(customs))
227
+ return items.some(function (item) {
228
+ return item === validator
229
+ })
230
+ },
231
+
232
+ _setupValidator: function ($validator, keypath, validation, validator, el, arg, init) {
233
+ var vm = this.vm
234
+
235
+ if (!getVal($validator[validation], keypath)) {
236
+ $validator._defineModelValidationScope(keypath)
237
+ if (el.tagName === 'INPUT' && el.type === 'radio') {
238
+ if (getVal(vm, keypath) === init) {
239
+ $validator._setInitialValue(keypath, init)
240
+ }
241
+ } else {
242
+ $validator._setInitialValue(keypath, init)
243
+ }
244
+ }
245
+
246
+ if (!getVal($validator[validation], [keypath, validator].join('.'))) {
247
+ $validator._defineValidatorToValidationScope(keypath, validator)
248
+ $validator._addValidator(keypath, validator, getVal(vm, arg) || arg)
249
+ }
250
+ },
251
+
252
+ _updateValidator: function ($validator, validator, keypath) {
253
+ var value = $validator.$get(keypath)
254
+ var el = this.el
255
+
256
+ if (this._init) {
257
+ value = this._init
258
+ delete this._init
259
+ }
260
+
261
+ if (el.tagName === 'INPUT' && el.type === 'radio') {
262
+ if (value === $validator.$get(keypath)) {
263
+ $validator._updateDirtyProperty(keypath, value)
264
+ }
265
+ } else {
266
+ $validator._updateDirtyProperty(keypath, value)
267
+ }
268
+
269
+ $validator._doValidate(keypath, validator, $validator.$get(keypath))
270
+ },
271
+
272
+ _teardownValidator: function (vm, $validator, keypath, validator) {
273
+ $validator._undefineValidatorToValidationScope(keypath, validator)
274
+ $validator._undefineModelValidationScope(keypath, validator)
275
+ }
276
+ })
277
+ }
278
+
279
+
280
+ /***/ },
281
+ /* 1 */
282
+ /***/ function(module, exports) {
283
+
284
+ /**
285
+ * Fundamental validate functions
286
+ */
287
+
288
+
289
+ /**
290
+ * required
291
+ *
292
+ * This function validate whether the value has been filled out.
293
+ *
294
+ * @param val
295
+ * @return {Boolean}
296
+ */
297
+
298
+ function required (val) {
299
+ if (Array.isArray(val)) {
300
+ return val.length > 0
301
+ } else if (typeof val === 'number') {
302
+ return true
303
+ } else if ((val !== null) && (typeof val === 'object')) {
304
+ return Object.keys(val).length > 0
305
+ } else {
306
+ return !val
307
+ ? false
308
+ : true
309
+ }
310
+ }
311
+
312
+
313
+ /**
314
+ * pattern
315
+ *
316
+ * This function validate whether the value matches the regex pattern
317
+ *
318
+ * @param val
319
+ * @param {String} pat
320
+ * @return {Boolean}
321
+ */
322
+
323
+ function pattern (val, pat) {
324
+ if (typeof pat !== 'string') { return false }
325
+
326
+ var match = pat.match(new RegExp('^/(.*?)/([gimy]*)$'))
327
+ if (!match) { return false }
328
+
329
+ return new RegExp(match[1], match[2]).test(val)
330
+ }
331
+
332
+
333
+ /**
334
+ * minLength
335
+ *
336
+ * This function validate whether the minimum length of the string.
337
+ *
338
+ * @param {String} val
339
+ * @param {String|Number} min
340
+ * @return {Boolean}
341
+ */
342
+
343
+ function minLength (val, min) {
344
+ return typeof val === 'string' &&
345
+ isInteger(min, 10) &&
346
+ val.length >= parseInt(min, 10)
347
+ }
348
+
349
+
350
+ /**
351
+ * maxLength
352
+ *
353
+ * This function validate whether the maximum length of the string.
354
+ *
355
+ * @param {String} val
356
+ * @param {String|Number} max
357
+ * @return {Boolean}
358
+ */
359
+
360
+ function maxLength (val, max) {
361
+ return typeof val === 'string' &&
362
+ isInteger(max, 10) &&
363
+ val.length <= parseInt(max, 10)
364
+ }
365
+
366
+
367
+ /**
368
+ * min
369
+ *
370
+ * This function validate whether the minimum value of the numberable value.
371
+ *
372
+ * @param {*} val
373
+ * @param {*} arg minimum
374
+ * @return {Boolean}
375
+ */
376
+
377
+ function min (val, arg) {
378
+ return !isNaN(+(val)) && !isNaN(+(arg)) && (+(val) >= +(arg))
379
+ }
380
+
381
+
382
+ /**
383
+ * max
384
+ *
385
+ * This function validate whether the maximum value of the numberable value.
386
+ *
387
+ * @param {*} val
388
+ * @param {*} arg maximum
389
+ * @return {Boolean}
390
+ */
391
+
392
+ function max (val, arg) {
393
+ return !isNaN(+(val)) && !isNaN(+(arg)) && (+(val) <= +(arg))
394
+ }
395
+
396
+
397
+ /**
398
+ * isInteger
399
+ *
400
+ * This function check whether the value of the string is integer.
401
+ *
402
+ * @param {String} val
403
+ * @return {Boolean}
404
+ * @private
405
+ */
406
+
407
+ function isInteger (val) {
408
+ return /^(-?[1-9]\d*|0)$/.test(val)
409
+ }
410
+
411
+
412
+ /**
413
+ * export(s)
414
+ */
415
+ module.exports = {
416
+ required: required,
417
+ pattern: pattern,
418
+ minLength: minLength,
419
+ maxLength: maxLength,
420
+ min: min,
421
+ max: max
422
+ }
423
+
424
+
425
+ /***/ },
426
+ /* 2 */
427
+ /***/ function(module, exports) {
428
+
429
+ /**
430
+ * Utilties
431
+ */
432
+
433
+
434
+ /**
435
+ * warn
436
+ *
437
+ * @param {String} msg
438
+ * @param {Error} [err]
439
+ *
440
+ */
441
+
442
+ exports.warn = function (msg, err) {
443
+ if (window.console) {
444
+ console.warn('[vue-validator] ' + msg)
445
+ if (err) {
446
+ console.warn(err.stack)
447
+ }
448
+ }
449
+ }
450
+
451
+ /**
452
+ * Get target validatable object
453
+ *
454
+ * @param {Object} validation
455
+ * @param {String} keypath
456
+ * @return {Object} validatable object
457
+ */
458
+
459
+ exports.getTarget = function (validation, keypath) {
460
+ var last = validation
461
+ var keys = keypath.split('.')
462
+ var key, obj
463
+ for (var i = 0; i < keys.length; i++) {
464
+ key = keys[i]
465
+ obj = last[key]
466
+ last = obj
467
+ if (!last) {
468
+ break
469
+ }
470
+ }
471
+ return last
472
+ }
473
+
474
+ /**
475
+ * Get custom validators
476
+ *
477
+ * @param {Object} options
478
+ * @return {Object}
479
+ */
480
+
481
+ exports.getCustomValidators = function (options) {
482
+ var opts = options
483
+ var validators = {}
484
+ var key
485
+ var context
486
+ do {
487
+ if (opts['validator'] && opts['validator']['validates']) {
488
+ for (key in opts['validator']['validates']) {
489
+ if (!validators.hasOwnProperty(key)) {
490
+ validators[key] = opts['validator']['validates'][key]
491
+ }
492
+ }
493
+ }
494
+ context = opts._context || opts._parent
495
+ if (context) {
496
+ opts = context.$options
497
+ }
498
+ } while (context || opts._parent)
499
+ return validators
500
+ }
501
+
502
+
503
+ /***/ },
504
+ /* 3 */
505
+ /***/ function(module, exports, __webpack_require__) {
506
+
507
+ /**
508
+ * Import(s)
509
+ */
510
+
511
+ var validates = __webpack_require__(1)
512
+ var _ = __webpack_require__(2)
513
+
514
+
515
+ /**
516
+ * Export(s)
517
+ */
518
+
519
+
520
+ /**
521
+ * `v-validator` component with mixin
522
+ */
523
+
524
+ module.exports = {
525
+ inherit: true,
526
+
527
+ created: function () {
528
+ this._initValidationVariables()
529
+ this._initOptions()
530
+ this._mixinCustomValidates()
531
+ this._defineProperties()
532
+ this._defineValidationScope()
533
+ },
534
+
535
+ methods: {
536
+ _getValidationNamespace: function (key) {
537
+ return this._namespace[key]
538
+ },
539
+
540
+ _initValidationVariables: function () {
541
+ this._validators = {}
542
+ this._validates = {}
543
+ this._initialValues = {}
544
+ for (var key in validates) {
545
+ this._validates[key] = validates[key]
546
+ }
547
+ this._validatorWatchers = {}
548
+ this._readyEvents = {}
549
+ },
550
+
551
+ _initOptions: function () {
552
+ this._namespace = getCustomNamespace(this.$options)
553
+ this._namespace.validation = this._namespace.validation || 'validation'
554
+ this._namespace.valid = this._namespace.valid || 'valid'
555
+ this._namespace.invalid = this._namespace.invalid || 'invalid'
556
+ this._namespace.dirty = this._namespace.dirty || 'dirty'
557
+ },
558
+
559
+ _mixinCustomValidates: function () {
560
+ var customs = _.getCustomValidators(this.$options)
561
+ for (var key in customs) {
562
+ this._validates[key] = customs[key]
563
+ }
564
+ },
565
+
566
+ _defineValidProperty: function (target, getter) {
567
+ Object.defineProperty(target, this._getValidationNamespace('valid'), {
568
+ enumerable: true,
569
+ configurable: true,
570
+ get: getter
571
+ })
572
+ },
573
+
574
+ _undefineValidProperty: function (target) {
575
+ delete target[this._getValidationNamespace('valid')]
576
+ },
577
+
578
+ _defineInvalidProperty: function (target) {
579
+ var self = this
580
+ Object.defineProperty(target, this._getValidationNamespace('invalid'), {
581
+ enumerable: true,
582
+ configurable: true,
583
+ get: function () {
584
+ return !target[self._getValidationNamespace('valid')]
585
+ }
586
+ })
587
+ },
588
+
589
+ _undefineInvalidProperty: function (target) {
590
+ delete target[this._getValidationNamespace('invalid')]
591
+ },
592
+
593
+ _defineDirtyProperty: function (target, getter) {
594
+ Object.defineProperty(target, this._getValidationNamespace('dirty'), {
595
+ enumerable: true,
596
+ configurable: true,
597
+ get: getter
598
+ })
599
+ },
600
+
601
+ _undefineDirtyProperty: function (target) {
602
+ delete target[this._getValidationNamespace('dirty')]
603
+ },
604
+
605
+ _defineProperties: function () {
606
+ var self = this
607
+
608
+ var walk = function (obj, propName, namespaces) {
609
+ var ret = false
610
+ var keys = Object.keys(obj)
611
+ var i = keys.length
612
+ var key, last
613
+ while (i--) {
614
+ key = keys[i]
615
+ last = obj[key]
616
+ if (!(key in namespaces) && typeof last === 'object') {
617
+ ret = walk(last, propName, namespaces)
618
+ if ((propName === self._getValidationNamespace('valid') && !ret) ||
619
+ (propName === self._getValidationNamespace('dirty') && ret)) {
620
+ break
621
+ }
622
+ } else if (key === propName && typeof last !== 'object') {
623
+ ret = last
624
+ if ((key === self._getValidationNamespace('valid') && !ret) ||
625
+ (key === self._getValidationNamespace('dirty') && ret)) {
626
+ break
627
+ }
628
+ }
629
+ }
630
+ return ret
631
+ }
632
+
633
+ this._defineValidProperty(this.$parent, function () {
634
+ var validationName = self._getValidationNamespace('validation')
635
+ var validName = self._getValidationNamespace('valid')
636
+ return walk(this[validationName], validName, self._namespace)
637
+ })
638
+
639
+ this._defineInvalidProperty(this.$parent)
640
+
641
+ this._defineDirtyProperty(this.$parent, function () {
642
+ var validationName = self._getValidationNamespace('validation')
643
+ var dirtyName = self._getValidationNamespace('dirty')
644
+ return walk(this[validationName], dirtyName, self._namespace)
645
+ })
646
+ },
647
+
648
+ _undefineProperties: function () {
649
+ this._undefineDirtyProperty(this.$parent)
650
+ this._undefineInvalidProperty(this.$parent)
651
+ this._undefineValidProperty(this.$parent)
652
+ },
653
+
654
+ _defineValidationScope: function () {
655
+ this.$parent.$add(this._getValidationNamespace('validation'), {})
656
+ },
657
+
658
+ _undefineValidationScope: function () {
659
+ var validationName = this._getValidationNamespace('validation')
660
+ this.$parent.$delete(validationName)
661
+ },
662
+
663
+ _defineModelValidationScope: function (keypath) {
664
+ var self = this
665
+ var validationName = this._getValidationNamespace('validation')
666
+ var dirtyName = this._getValidationNamespace('dirty')
667
+
668
+ var keys = keypath.split('.')
669
+ var last = this[validationName]
670
+ var obj, key
671
+ for (var i = 0; i < keys.length; i++) {
672
+ key = keys[i]
673
+ obj = last[key]
674
+ if (!obj) {
675
+ obj = {}
676
+ last.$add(key, obj)
677
+ }
678
+ last = obj
679
+ }
680
+ last.$add(dirtyName, false)
681
+
682
+ this._defineValidProperty(last, function () {
683
+ var ret = true
684
+ var validators = self._validators[keypath]
685
+ var i = validators.length
686
+ var validator
687
+ while (i--) {
688
+ validator = validators[i]
689
+ if (last[validator.name]) {
690
+ ret = false
691
+ break
692
+ }
693
+ }
694
+ return ret
695
+ })
696
+ this._defineInvalidProperty(last)
697
+
698
+ this._validators[keypath] = []
699
+
700
+ this._watchModel(keypath, function (val, old) {
701
+ self._updateDirtyProperty(keypath, val)
702
+ self._validators[keypath].forEach(function (validator) {
703
+ self._doValidate(keypath, validator.name, val)
704
+ })
705
+ })
706
+ },
707
+
708
+ _undefineModelValidationScope: function (keypath, validator) {
709
+ if (this.$parent) {
710
+ var targetPath = [this._getValidationNamespace('validation'), keypath].join('.')
711
+ var target = this.$parent.$get(targetPath)
712
+ if (target && Object.keys(target).length === 3 &&
713
+ this._getValidationNamespace('valid') in target &&
714
+ this._getValidationNamespace('invalid') in target &&
715
+ this._getValidationNamespace('dirty') in target) {
716
+ this._unwatchModel(keypath)
717
+ this._undefineDirtyProperty(target)
718
+ this._undefineInvalidProperty(target)
719
+ this._undefineValidProperty(target)
720
+ removeValidationProperties(
721
+ this.$parent.$get(this._getValidationNamespace('validation')),
722
+ keypath
723
+ )
724
+ }
725
+ }
726
+ },
727
+
728
+ _defineValidatorToValidationScope: function (keypath, validator) {
729
+ var target = _.getTarget(this[this._getValidationNamespace('validation')], keypath)
730
+ target.$add(validator, null)
731
+ },
732
+
733
+ _undefineValidatorToValidationScope: function (keypath, validator) {
734
+ var validationName = this._getValidationNamespace('validation')
735
+ if (this.$parent) {
736
+ var targetPath = [validationName, keypath].join('.')
737
+ var target = this.$parent.$get(targetPath)
738
+ if (target) {
739
+ target.$delete(validator)
740
+ }
741
+ }
742
+ },
743
+
744
+ _getInitialValue: function (keypath) {
745
+ return this._initialValues[keypath]
746
+ },
747
+
748
+ _setInitialValue: function (keypath, val) {
749
+ this._initialValues[keypath] = val
750
+ },
751
+
752
+ _addValidator: function (keypath, validator, arg) {
753
+ this._validators[keypath].push({ name: validator, arg: arg })
754
+ },
755
+
756
+ _changeValidator: function (keypath, validator, arg) {
757
+ var validators = this._validators[keypath]
758
+ var i = validators.length
759
+ while (i--) {
760
+ if (validators[i].name === validator) {
761
+ validators[i].arg = arg
762
+ break
763
+ }
764
+ }
765
+ },
766
+
767
+ _findValidator: function (keypath, validator) {
768
+ var found = null
769
+ var validators = this._validators[keypath]
770
+ var i = validators.length
771
+ while (i--) {
772
+ if (validators[i].name === validator) {
773
+ found = validators[i]
774
+ break
775
+ }
776
+ }
777
+ return found
778
+ },
779
+
780
+ _watchModel: function (keypath, fn) {
781
+ this._validatorWatchers[keypath] =
782
+ this.$watch(keypath, fn, { deep: false, immediate: true })
783
+ },
784
+
785
+ _unwatchModel: function (keypath) {
786
+ var unwatch = this._validatorWatchers[keypath]
787
+ if (unwatch) {
788
+ unwatch()
789
+ delete this._validatorWatchers[keypath]
790
+ }
791
+ },
792
+
793
+ _addReadyEvents: function (id, event) {
794
+ this._readyEvents[id] = event
795
+ },
796
+
797
+ _getReadyEvents: function (id) {
798
+ return this._readyEvents[id]
799
+ },
800
+
801
+ _isRegistedReadyEvent: function (id) {
802
+ return id in this._readyEvents
803
+ },
804
+
805
+ _updateDirtyProperty: function (keypath, val) {
806
+ var validationName = this._getValidationNamespace('validation')
807
+ var dirtyName = this._getValidationNamespace('dirty')
808
+
809
+ var target = _.getTarget(this[validationName], keypath)
810
+ if (target) {
811
+ target.$set(dirtyName, this._getInitialValue(keypath) !== val)
812
+ }
813
+ },
814
+
815
+ _doValidate: function (keypath, validateName, val) {
816
+ var validationName = this._getValidationNamespace('validation')
817
+
818
+ var target = _.getTarget(this[validationName], keypath)
819
+ var validator = this._findValidator(keypath, validateName)
820
+ if (target && validator) {
821
+ this._invokeValidator(
822
+ this._validates[validateName],
823
+ val, validator.arg,
824
+ function (result) {
825
+ target.$set(validateName, !result)
826
+ })
827
+ }
828
+ },
829
+
830
+ _invokeValidator: function (validator, val, arg, fn) {
831
+ var future = validator.call(this, val, arg)
832
+ if (typeof future === 'function') { // async
833
+ if (future.resolved) {
834
+ // cached
835
+ fn(future.resolved)
836
+ } else if (future.requested) {
837
+ // pool callbacks
838
+ future.pendingCallbacks.push(fn)
839
+ } else {
840
+ future.requested = true
841
+ var fns = future.pendingCallbacks = [fn]
842
+ future(function resolve () {
843
+ future.resolved = true
844
+ for (var i = 0, l = fns.length; i < l; i++) {
845
+ fns[i](true)
846
+ }
847
+ }, function reject () {
848
+ fn(false)
849
+ })
850
+ }
851
+ } else { // sync
852
+ fn(future)
853
+ }
854
+ }
855
+ }
856
+ }
857
+
858
+ /**
859
+ * Remove properties from target validation
860
+ *
861
+ * @param {Object} validation
862
+ * @param {String} keypath
863
+ */
864
+
865
+ function removeValidationProperties (validation, keypath) {
866
+ var keys = keypath.split('.')
867
+ var key, obj
868
+ while (keys.length) {
869
+ key = keys.pop()
870
+ if (keys.length !== 0) {
871
+ obj = _.getTarget(validation, keys.join('.'))
872
+ obj.$delete(key)
873
+ } else {
874
+ validation.$delete(key)
875
+ }
876
+ }
877
+ }
878
+
879
+ /**
880
+ * Get custom namespace
881
+ *
882
+ * @param {Object} options
883
+ * @return {Object}
884
+ */
885
+
886
+ function getCustomNamespace (options) {
887
+ var namespace = {}
888
+ var key
889
+ var context
890
+ do {
891
+ if (options['validator'] && options['validator']['namespace']) {
892
+ for (key in options['validator']['namespace']) {
893
+ if (!namespace.hasOwnProperty(key)) {
894
+ namespace[key] = options['validator']['namespace'][key]
895
+ }
896
+ }
897
+ }
898
+ context = options._context || options._parent
899
+ if (context) {
900
+ options = context.$options
901
+ }
902
+ } while (context || options._parent)
903
+ return namespace
904
+ }
905
+
906
+
907
+ /***/ }
908
+ /******/ ])
909
+ });
910
+ ;