vueonrails 0.1.0

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.
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
+ ;