fluentd-ui 0.3.8 → 0.3.9

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.

Potentially problematic release.


This version of fluentd-ui might be problematic. Click here for more details.

Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +9 -0
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +4 -1
  5. data/app/assets/javascripts/vue/fluent_log.js +4 -4
  6. data/app/assets/javascripts/vue/in_tail_format.js +43 -49
  7. data/app/assets/javascripts/{alert.js → vue/notification.js} +21 -7
  8. data/app/assets/javascripts/vue/settings.js +121 -0
  9. data/app/assets/javascripts/vue/treeview.js +3 -3
  10. data/app/assets/stylesheets/common.css.scss +7 -1
  11. data/app/controllers/api/settings_controller.rb +55 -0
  12. data/app/controllers/api_controller.rb +6 -2
  13. data/app/controllers/concerns/setting_concern.rb +2 -2
  14. data/app/controllers/fluentd/settings_controller.rb +17 -2
  15. data/app/models/fluentd/setting/config.rb +39 -0
  16. data/app/views/api/settings/_element.json.jbuilder +6 -0
  17. data/app/views/api/settings/index.json.jbuilder +3 -0
  18. data/app/views/api/settings/show.json.jbuilder +1 -0
  19. data/app/views/fluentd/settings/edit.html.haml +3 -0
  20. data/app/views/fluentd/settings/source_and_output.html.haml +19 -2
  21. data/app/views/layouts/application.html.erb +1 -30
  22. data/app/views/shared/vue/_in_tail_format.html.erb +11 -36
  23. data/app/views/shared/vue/_notification.html.erb +31 -0
  24. data/app/views/shared/vue/_setting.html.erb +23 -0
  25. data/app/views/shared/vue/_treeview.html.erb +2 -2
  26. data/bower.json +1 -1
  27. data/config/application.rb +1 -0
  28. data/config/locales/translation_en.yml +11 -7
  29. data/config/locales/translation_ja.yml +4 -0
  30. data/config/routes.rb +2 -0
  31. data/lib/fluentd-ui/version.rb +1 -1
  32. data/spec/features/fluentd/setting/source_and_output_spec.rb +157 -0
  33. data/spec/spec_helper.rb +1 -0
  34. data/spec/support/javascript_macro.rb +21 -0
  35. data/vendor/assets/javascripts/bower/vue/.bower.json +7 -7
  36. data/vendor/assets/javascripts/bower/vue/LICENSE +1 -1
  37. data/vendor/assets/javascripts/bower/vue/dist/vue.js +7822 -4768
  38. data/vendor/assets/javascripts/bower/vue/dist/vue.min.js +7 -7
  39. data/vendor/assets/javascripts/bower/vue/src/api/child.js +53 -0
  40. data/vendor/assets/javascripts/bower/vue/src/api/data.js +161 -0
  41. data/vendor/assets/javascripts/bower/vue/src/api/dom.js +211 -0
  42. data/vendor/assets/javascripts/bower/vue/src/api/events.js +176 -0
  43. data/vendor/assets/javascripts/bower/vue/src/api/global.js +146 -0
  44. data/vendor/assets/javascripts/bower/vue/src/api/lifecycle.js +144 -0
  45. data/vendor/assets/javascripts/bower/vue/src/batcher.js +52 -32
  46. data/vendor/assets/javascripts/bower/vue/src/cache.js +112 -0
  47. data/vendor/assets/javascripts/bower/vue/src/compiler/compile.js +549 -0
  48. data/vendor/assets/javascripts/bower/vue/src/compiler/transclude.js +163 -0
  49. data/vendor/assets/javascripts/bower/vue/src/config.js +74 -14
  50. data/vendor/assets/javascripts/bower/vue/src/directive.js +179 -219
  51. data/vendor/assets/javascripts/bower/vue/src/directives/attr.js +32 -0
  52. data/vendor/assets/javascripts/bower/vue/src/directives/class.js +18 -0
  53. data/vendor/assets/javascripts/bower/vue/src/directives/cloak.js +12 -0
  54. data/vendor/assets/javascripts/bower/vue/src/directives/component.js +214 -0
  55. data/vendor/assets/javascripts/bower/vue/src/directives/el.js +13 -0
  56. data/vendor/assets/javascripts/bower/vue/src/directives/html.js +30 -34
  57. data/vendor/assets/javascripts/bower/vue/src/directives/if.js +77 -46
  58. data/vendor/assets/javascripts/bower/vue/src/directives/index.js +22 -129
  59. data/vendor/assets/javascripts/bower/vue/src/directives/model/checkbox.js +25 -0
  60. data/vendor/assets/javascripts/bower/vue/src/directives/model/default.js +123 -0
  61. data/vendor/assets/javascripts/bower/vue/src/directives/model/index.js +56 -0
  62. data/vendor/assets/javascripts/bower/vue/src/directives/model/radio.js +26 -0
  63. data/vendor/assets/javascripts/bower/vue/src/directives/model/select.js +166 -0
  64. data/vendor/assets/javascripts/bower/vue/src/directives/on.js +51 -50
  65. data/vendor/assets/javascripts/bower/vue/src/directives/partial.js +36 -42
  66. data/vendor/assets/javascripts/bower/vue/src/directives/ref.js +24 -0
  67. data/vendor/assets/javascripts/bower/vue/src/directives/repeat.js +477 -226
  68. data/vendor/assets/javascripts/bower/vue/src/directives/show.js +8 -0
  69. data/vendor/assets/javascripts/bower/vue/src/directives/style.js +49 -37
  70. data/vendor/assets/javascripts/bower/vue/src/directives/text.js +15 -0
  71. data/vendor/assets/javascripts/bower/vue/src/directives/transition.js +12 -0
  72. data/vendor/assets/javascripts/bower/vue/src/directives/with.js +38 -41
  73. data/vendor/assets/javascripts/bower/vue/src/filters/array-filters.js +87 -0
  74. data/vendor/assets/javascripts/bower/vue/src/filters/index.js +135 -0
  75. data/vendor/assets/javascripts/bower/vue/src/instance/compile.js +71 -0
  76. data/vendor/assets/javascripts/bower/vue/src/instance/events.js +122 -0
  77. data/vendor/assets/javascripts/bower/vue/src/instance/init.js +76 -0
  78. data/vendor/assets/javascripts/bower/vue/src/instance/scope.js +217 -0
  79. data/vendor/assets/javascripts/bower/vue/src/observer/array.js +90 -0
  80. data/vendor/assets/javascripts/bower/vue/src/observer/dep.js +50 -0
  81. data/vendor/assets/javascripts/bower/vue/src/observer/index.js +235 -0
  82. data/vendor/assets/javascripts/bower/vue/src/observer/object.js +75 -0
  83. data/vendor/assets/javascripts/bower/vue/src/parsers/directive.js +159 -0
  84. data/vendor/assets/javascripts/bower/vue/src/parsers/expression.js +226 -0
  85. data/vendor/assets/javascripts/bower/vue/src/parsers/path.js +300 -0
  86. data/vendor/assets/javascripts/bower/vue/src/parsers/template.js +246 -0
  87. data/vendor/assets/javascripts/bower/vue/src/parsers/text.js +178 -0
  88. data/vendor/assets/javascripts/bower/vue/src/transition/css.js +189 -0
  89. data/vendor/assets/javascripts/bower/vue/src/transition/index.js +151 -0
  90. data/vendor/assets/javascripts/bower/vue/src/transition/js.js +43 -0
  91. data/vendor/assets/javascripts/bower/vue/src/util/debug.js +50 -0
  92. data/vendor/assets/javascripts/bower/vue/src/util/dom.js +176 -0
  93. data/vendor/assets/javascripts/bower/vue/src/util/env.js +74 -0
  94. data/vendor/assets/javascripts/bower/vue/src/util/filter.js +72 -0
  95. data/vendor/assets/javascripts/bower/vue/src/util/index.js +8 -0
  96. data/vendor/assets/javascripts/bower/vue/src/util/lang.js +175 -0
  97. data/vendor/assets/javascripts/bower/vue/src/util/merge-option.js +258 -0
  98. data/vendor/assets/javascripts/bower/vue/src/vue.js +84 -0
  99. data/vendor/assets/javascripts/bower/vue/src/watcher.js +240 -0
  100. metadata +65 -20
  101. data/app/assets/javascripts/setting_format.js +0 -15
  102. data/vendor/assets/javascripts/bower/vue/src/binding.js +0 -103
  103. data/vendor/assets/javascripts/bower/vue/src/compiler.js +0 -1037
  104. data/vendor/assets/javascripts/bower/vue/src/deps-parser.js +0 -65
  105. data/vendor/assets/javascripts/bower/vue/src/directives/model.js +0 -174
  106. data/vendor/assets/javascripts/bower/vue/src/directives/view.js +0 -56
  107. data/vendor/assets/javascripts/bower/vue/src/emitter.js +0 -97
  108. data/vendor/assets/javascripts/bower/vue/src/exp-parser.js +0 -190
  109. data/vendor/assets/javascripts/bower/vue/src/filters.js +0 -191
  110. data/vendor/assets/javascripts/bower/vue/src/fragment.js +0 -67
  111. data/vendor/assets/javascripts/bower/vue/src/main.js +0 -188
  112. data/vendor/assets/javascripts/bower/vue/src/observer.js +0 -446
  113. data/vendor/assets/javascripts/bower/vue/src/template-parser.js +0 -46
  114. data/vendor/assets/javascripts/bower/vue/src/text-parser.js +0 -96
  115. data/vendor/assets/javascripts/bower/vue/src/transition.js +0 -228
  116. data/vendor/assets/javascripts/bower/vue/src/utils.js +0 -326
  117. data/vendor/assets/javascripts/bower/vue/src/viewmodel.js +0 -190
@@ -1,129 +1,22 @@
1
- var utils = require('../utils'),
2
- config = require('../config'),
3
- transition = require('../transition'),
4
- directives = module.exports = utils.hash()
5
-
6
- /**
7
- * Nest and manage a Child VM
8
- */
9
- directives.component = {
10
- isLiteral: true,
11
- bind: function () {
12
- if (!this.el.vue_vm) {
13
- this.childVM = new this.Ctor({
14
- el: this.el,
15
- parent: this.vm
16
- })
17
- }
18
- },
19
- unbind: function () {
20
- if (this.childVM) {
21
- this.childVM.$destroy()
22
- }
23
- }
24
- }
25
-
26
- /**
27
- * Binding HTML attributes
28
- */
29
- directives.attr = {
30
- bind: function () {
31
- var params = this.vm.$options.paramAttributes
32
- this.isParam = params && params.indexOf(this.arg) > -1
33
- },
34
- update: function (value) {
35
- if (value || value === 0) {
36
- this.el.setAttribute(this.arg, value)
37
- } else {
38
- this.el.removeAttribute(this.arg)
39
- }
40
- if (this.isParam) {
41
- this.vm[this.arg] = utils.checkNumber(value)
42
- }
43
- }
44
- }
45
-
46
- /**
47
- * Binding textContent
48
- */
49
- directives.text = {
50
- bind: function () {
51
- this.attr = this.el.nodeType === 3
52
- ? 'nodeValue'
53
- : 'textContent'
54
- },
55
- update: function (value) {
56
- this.el[this.attr] = utils.guard(value)
57
- }
58
- }
59
-
60
- /**
61
- * Binding CSS display property
62
- */
63
- directives.show = function (value) {
64
- var el = this.el,
65
- target = value ? '' : 'none',
66
- change = function () {
67
- el.style.display = target
68
- }
69
- transition(el, value ? 1 : -1, change, this.compiler)
70
- }
71
-
72
- /**
73
- * Binding CSS classes
74
- */
75
- directives['class'] = function (value) {
76
- if (this.arg) {
77
- utils[value ? 'addClass' : 'removeClass'](this.el, this.arg)
78
- } else {
79
- if (this.lastVal) {
80
- utils.removeClass(this.el, this.lastVal)
81
- }
82
- if (value) {
83
- utils.addClass(this.el, value)
84
- this.lastVal = value
85
- }
86
- }
87
- }
88
-
89
- /**
90
- * Only removed after the owner VM is ready
91
- */
92
- directives.cloak = {
93
- isEmpty: true,
94
- bind: function () {
95
- var el = this.el
96
- this.compiler.observer.once('hook:ready', function () {
97
- el.removeAttribute(config.prefix + '-cloak')
98
- })
99
- }
100
- }
101
-
102
- /**
103
- * Store a reference to self in parent VM's $
104
- */
105
- directives.ref = {
106
- isLiteral: true,
107
- bind: function () {
108
- var id = this.expression
109
- if (id) {
110
- this.vm.$parent.$[id] = this.vm
111
- }
112
- },
113
- unbind: function () {
114
- var id = this.expression
115
- if (id) {
116
- delete this.vm.$parent.$[id]
117
- }
118
- }
119
- }
120
-
121
- directives.on = require('./on')
122
- directives.repeat = require('./repeat')
123
- directives.model = require('./model')
124
- directives['if'] = require('./if')
125
- directives['with'] = require('./with')
126
- directives.html = require('./html')
127
- directives.style = require('./style')
128
- directives.partial = require('./partial')
129
- directives.view = require('./view')
1
+ // manipulation directives
2
+ exports.text = require('./text')
3
+ exports.html = require('./html')
4
+ exports.attr = require('./attr')
5
+ exports.show = require('./show')
6
+ exports['class'] = require('./class')
7
+ exports.el = require('./el')
8
+ exports.ref = require('./ref')
9
+ exports.cloak = require('./cloak')
10
+ exports.style = require('./style')
11
+ exports.partial = require('./partial')
12
+ exports.transition = require('./transition')
13
+
14
+ // event listener directives
15
+ exports.on = require('./on')
16
+ exports.model = require('./model')
17
+
18
+ // child vm directives
19
+ exports.component = require('./component')
20
+ exports.repeat = require('./repeat')
21
+ exports['if'] = require('./if')
22
+ exports['with'] = require('./with')
@@ -0,0 +1,25 @@
1
+ var _ = require('../../util')
2
+
3
+ module.exports = {
4
+
5
+ bind: function () {
6
+ var self = this
7
+ var el = this.el
8
+ this.listener = function () {
9
+ self.set(el.checked, true)
10
+ }
11
+ _.on(el, 'change', this.listener)
12
+ if (el.checked) {
13
+ this._initValue = el.checked
14
+ }
15
+ },
16
+
17
+ update: function (value) {
18
+ this.el.checked = !!value
19
+ },
20
+
21
+ unbind: function () {
22
+ _.off(this.el, 'change', this.listener)
23
+ }
24
+
25
+ }
@@ -0,0 +1,123 @@
1
+ var _ = require('../../util')
2
+
3
+ module.exports = {
4
+
5
+ bind: function () {
6
+ var self = this
7
+ var el = this.el
8
+
9
+ // check params
10
+ // - lazy: update model on "change" instead of "input"
11
+ var lazy = this._checkParam('lazy') != null
12
+ // - number: cast value into number when updating model.
13
+ var number = this._checkParam('number') != null
14
+
15
+ // handle composition events.
16
+ // http://blog.evanyou.me/2014/01/03/composition-event/
17
+ var cpLocked = false
18
+ this.cpLock = function () {
19
+ cpLocked = true
20
+ }
21
+ this.cpUnlock = function () {
22
+ cpLocked = false
23
+ // in IE11 the "compositionend" event fires AFTER
24
+ // the "input" event, so the input handler is blocked
25
+ // at the end... have to call it here.
26
+ set()
27
+ }
28
+ _.on(el,'compositionstart', this.cpLock)
29
+ _.on(el,'compositionend', this.cpUnlock)
30
+
31
+ // shared setter
32
+ function set () {
33
+ self.set(
34
+ number ? _.toNumber(el.value) : el.value,
35
+ true
36
+ )
37
+ }
38
+
39
+ // if the directive has filters, we need to
40
+ // record cursor position and restore it after updating
41
+ // the input with the filtered value.
42
+ // also force update for type="range" inputs to enable
43
+ // "lock in range" (see #506)
44
+ this.listener = this.filters || el.type === 'range'
45
+ ? function textInputListener () {
46
+ if (cpLocked) return
47
+ var charsOffset
48
+ // some HTML5 input types throw error here
49
+ try {
50
+ // record how many chars from the end of input
51
+ // the cursor was at
52
+ charsOffset = el.value.length - el.selectionStart
53
+ } catch (e) {}
54
+ // Fix IE10/11 infinite update cycle
55
+ // https://github.com/yyx990803/vue/issues/592
56
+ /* istanbul ignore if */
57
+ if (charsOffset < 0) {
58
+ return
59
+ }
60
+ set()
61
+ _.nextTick(function () {
62
+ // force a value update, because in
63
+ // certain cases the write filters output the
64
+ // same result for different input values, and
65
+ // the Observer set events won't be triggered.
66
+ var newVal = self._watcher.value
67
+ self.update(newVal)
68
+ if (charsOffset != null) {
69
+ var cursorPos =
70
+ _.toString(newVal).length - charsOffset
71
+ el.setSelectionRange(cursorPos, cursorPos)
72
+ }
73
+ })
74
+ }
75
+ : function textInputListener () {
76
+ if (cpLocked) return
77
+ set()
78
+ }
79
+
80
+ this.event = lazy ? 'change' : 'input'
81
+ _.on(el, this.event, this.listener)
82
+
83
+ // IE9 doesn't fire input event on backspace/del/cut
84
+ if (!lazy && _.isIE9) {
85
+ this.onCut = function () {
86
+ _.nextTick(self.listener)
87
+ }
88
+ this.onDel = function (e) {
89
+ if (e.keyCode === 46 || e.keyCode === 8) {
90
+ self.listener()
91
+ }
92
+ }
93
+ _.on(el, 'cut', this.onCut)
94
+ _.on(el, 'keyup', this.onDel)
95
+ }
96
+
97
+ // set initial value if present
98
+ if (
99
+ el.hasAttribute('value') ||
100
+ (el.tagName === 'TEXTAREA' && el.value.trim())
101
+ ) {
102
+ this._initValue = number
103
+ ? _.toNumber(el.value)
104
+ : el.value
105
+ }
106
+ },
107
+
108
+ update: function (value) {
109
+ this.el.value = _.toString(value)
110
+ },
111
+
112
+ unbind: function () {
113
+ var el = this.el
114
+ _.off(el, this.event, this.listener)
115
+ _.off(el,'compositionstart', this.cpLock)
116
+ _.off(el,'compositionend', this.cpUnlock)
117
+ if (this.onCut) {
118
+ _.off(el,'cut', this.onCut)
119
+ _.off(el,'keyup', this.onDel)
120
+ }
121
+ }
122
+
123
+ }
@@ -0,0 +1,56 @@
1
+ var _ = require('../../util')
2
+
3
+ var handlers = {
4
+ _default: require('./default'),
5
+ radio: require('./radio'),
6
+ select: require('./select'),
7
+ checkbox: require('./checkbox')
8
+ }
9
+
10
+ module.exports = {
11
+
12
+ priority: 800,
13
+ twoWay: true,
14
+ handlers: handlers,
15
+
16
+ /**
17
+ * Possible elements:
18
+ * <select>
19
+ * <textarea>
20
+ * <input type="*">
21
+ * - text
22
+ * - checkbox
23
+ * - radio
24
+ * - number
25
+ * - TODO: more types may be supplied as a plugin
26
+ */
27
+
28
+ bind: function () {
29
+ // friendly warning...
30
+ var filters = this.filters
31
+ if (filters && filters.read && !filters.write) {
32
+ _.warn(
33
+ 'It seems you are using a read-only filter with ' +
34
+ 'v-model. You might want to use a two-way filter ' +
35
+ 'to ensure correct behavior.'
36
+ )
37
+ }
38
+ var el = this.el
39
+ var tag = el.tagName
40
+ var handler
41
+ if (tag === 'INPUT') {
42
+ handler = handlers[el.type] || handlers._default
43
+ } else if (tag === 'SELECT') {
44
+ handler = handlers.select
45
+ } else if (tag === 'TEXTAREA') {
46
+ handler = handlers._default
47
+ } else {
48
+ _.warn("v-model doesn't support element type: " + tag)
49
+ return
50
+ }
51
+ handler.bind.call(this)
52
+ this.update = handler.update
53
+ this.unbind = handler.unbind
54
+ }
55
+
56
+ }
@@ -0,0 +1,26 @@
1
+ var _ = require('../../util')
2
+
3
+ module.exports = {
4
+
5
+ bind: function () {
6
+ var self = this
7
+ var el = this.el
8
+ this.listener = function () {
9
+ self.set(el.value, true)
10
+ }
11
+ _.on(el, 'change', this.listener)
12
+ if (el.checked) {
13
+ this._initValue = el.value
14
+ }
15
+ },
16
+
17
+ update: function (value) {
18
+ /* jshint eqeqeq: false */
19
+ this.el.checked = value == this.el.value
20
+ },
21
+
22
+ unbind: function () {
23
+ _.off(this.el, 'change', this.listener)
24
+ }
25
+
26
+ }
@@ -0,0 +1,166 @@
1
+ var _ = require('../../util')
2
+ var Watcher = require('../../watcher')
3
+
4
+ module.exports = {
5
+
6
+ bind: function () {
7
+ var self = this
8
+ var el = this.el
9
+ // check options param
10
+ var optionsParam = this._checkParam('options')
11
+ if (optionsParam) {
12
+ initOptions.call(this, optionsParam)
13
+ }
14
+ this.multiple = el.hasAttribute('multiple')
15
+ this.listener = function () {
16
+ var value = self.multiple
17
+ ? getMultiValue(el)
18
+ : el.value
19
+ self.set(value, true)
20
+ }
21
+ _.on(el, 'change', this.listener)
22
+ checkInitialValue.call(this)
23
+ },
24
+
25
+ update: function (value) {
26
+ /* jshint eqeqeq: false */
27
+ var el = this.el
28
+ el.selectedIndex = -1
29
+ var multi = this.multiple && _.isArray(value)
30
+ var options = el.options
31
+ var i = options.length
32
+ var option
33
+ while (i--) {
34
+ option = options[i]
35
+ option.selected = multi
36
+ ? indexOf(value, option.value) > -1
37
+ : value == option.value
38
+ }
39
+ },
40
+
41
+ unbind: function () {
42
+ _.off(this.el, 'change', this.listener)
43
+ if (this.optionWatcher) {
44
+ this.optionWatcher.teardown()
45
+ }
46
+ }
47
+
48
+ }
49
+
50
+ /**
51
+ * Initialize the option list from the param.
52
+ *
53
+ * @param {String} expression
54
+ */
55
+
56
+ function initOptions (expression) {
57
+ var self = this
58
+ function optionUpdateWatcher (value) {
59
+ if (_.isArray(value)) {
60
+ self.el.innerHTML = ''
61
+ buildOptions(self.el, value)
62
+ if (self._watcher) {
63
+ self.update(self._watcher.value)
64
+ }
65
+ } else {
66
+ _.warn('Invalid options value for v-model: ' + value)
67
+ }
68
+ }
69
+ this.optionWatcher = new Watcher(
70
+ this.vm,
71
+ expression,
72
+ optionUpdateWatcher
73
+ )
74
+ // update with initial value
75
+ optionUpdateWatcher(this.optionWatcher.value)
76
+ }
77
+
78
+ /**
79
+ * Build up option elements. IE9 doesn't create options
80
+ * when setting innerHTML on <select> elements, so we have
81
+ * to use DOM API here.
82
+ *
83
+ * @param {Element} parent - a <select> or an <optgroup>
84
+ * @param {Array} options
85
+ */
86
+
87
+ function buildOptions (parent, options) {
88
+ var op, el
89
+ for (var i = 0, l = options.length; i < l; i++) {
90
+ op = options[i]
91
+ if (!op.options) {
92
+ el = document.createElement('option')
93
+ if (typeof op === 'string') {
94
+ el.text = el.value = op
95
+ } else {
96
+ el.text = op.text
97
+ el.value = op.value
98
+ }
99
+ } else {
100
+ el = document.createElement('optgroup')
101
+ el.label = op.label
102
+ buildOptions(el, op.options)
103
+ }
104
+ parent.appendChild(el)
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Check the initial value for selected options.
110
+ */
111
+
112
+ function checkInitialValue () {
113
+ var initValue
114
+ var options = this.el.options
115
+ for (var i = 0, l = options.length; i < l; i++) {
116
+ if (options[i].hasAttribute('selected')) {
117
+ if (this.multiple) {
118
+ (initValue || (initValue = []))
119
+ .push(options[i].value)
120
+ } else {
121
+ initValue = options[i].value
122
+ }
123
+ }
124
+ }
125
+ if (initValue) {
126
+ this._initValue = initValue
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Helper to extract a value array for select[multiple]
132
+ *
133
+ * @param {SelectElement} el
134
+ * @return {Array}
135
+ */
136
+
137
+ function getMultiValue (el) {
138
+ return Array.prototype.filter
139
+ .call(el.options, filterSelected)
140
+ .map(getOptionValue)
141
+ }
142
+
143
+ function filterSelected (op) {
144
+ return op.selected
145
+ }
146
+
147
+ function getOptionValue (op) {
148
+ return op.value || op.text
149
+ }
150
+
151
+ /**
152
+ * Native Array.indexOf uses strict equal, but in this
153
+ * case we need to match string/numbers with soft equal.
154
+ *
155
+ * @param {Array} arr
156
+ * @param {*} val
157
+ */
158
+
159
+ function indexOf (arr, val) {
160
+ /* jshint eqeqeq: false */
161
+ var i = arr.length
162
+ while (i--) {
163
+ if (arr[i] == val) return i
164
+ }
165
+ return -1
166
+ }