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.
- checksums.yaml +4 -4
- data/ChangeLog +9 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +4 -1
- data/app/assets/javascripts/vue/fluent_log.js +4 -4
- data/app/assets/javascripts/vue/in_tail_format.js +43 -49
- data/app/assets/javascripts/{alert.js → vue/notification.js} +21 -7
- data/app/assets/javascripts/vue/settings.js +121 -0
- data/app/assets/javascripts/vue/treeview.js +3 -3
- data/app/assets/stylesheets/common.css.scss +7 -1
- data/app/controllers/api/settings_controller.rb +55 -0
- data/app/controllers/api_controller.rb +6 -2
- data/app/controllers/concerns/setting_concern.rb +2 -2
- data/app/controllers/fluentd/settings_controller.rb +17 -2
- data/app/models/fluentd/setting/config.rb +39 -0
- data/app/views/api/settings/_element.json.jbuilder +6 -0
- data/app/views/api/settings/index.json.jbuilder +3 -0
- data/app/views/api/settings/show.json.jbuilder +1 -0
- data/app/views/fluentd/settings/edit.html.haml +3 -0
- data/app/views/fluentd/settings/source_and_output.html.haml +19 -2
- data/app/views/layouts/application.html.erb +1 -30
- data/app/views/shared/vue/_in_tail_format.html.erb +11 -36
- data/app/views/shared/vue/_notification.html.erb +31 -0
- data/app/views/shared/vue/_setting.html.erb +23 -0
- data/app/views/shared/vue/_treeview.html.erb +2 -2
- data/bower.json +1 -1
- data/config/application.rb +1 -0
- data/config/locales/translation_en.yml +11 -7
- data/config/locales/translation_ja.yml +4 -0
- data/config/routes.rb +2 -0
- data/lib/fluentd-ui/version.rb +1 -1
- data/spec/features/fluentd/setting/source_and_output_spec.rb +157 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/javascript_macro.rb +21 -0
- data/vendor/assets/javascripts/bower/vue/.bower.json +7 -7
- data/vendor/assets/javascripts/bower/vue/LICENSE +1 -1
- data/vendor/assets/javascripts/bower/vue/dist/vue.js +7822 -4768
- data/vendor/assets/javascripts/bower/vue/dist/vue.min.js +7 -7
- data/vendor/assets/javascripts/bower/vue/src/api/child.js +53 -0
- data/vendor/assets/javascripts/bower/vue/src/api/data.js +161 -0
- data/vendor/assets/javascripts/bower/vue/src/api/dom.js +211 -0
- data/vendor/assets/javascripts/bower/vue/src/api/events.js +176 -0
- data/vendor/assets/javascripts/bower/vue/src/api/global.js +146 -0
- data/vendor/assets/javascripts/bower/vue/src/api/lifecycle.js +144 -0
- data/vendor/assets/javascripts/bower/vue/src/batcher.js +52 -32
- data/vendor/assets/javascripts/bower/vue/src/cache.js +112 -0
- data/vendor/assets/javascripts/bower/vue/src/compiler/compile.js +549 -0
- data/vendor/assets/javascripts/bower/vue/src/compiler/transclude.js +163 -0
- data/vendor/assets/javascripts/bower/vue/src/config.js +74 -14
- data/vendor/assets/javascripts/bower/vue/src/directive.js +179 -219
- data/vendor/assets/javascripts/bower/vue/src/directives/attr.js +32 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/class.js +18 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/cloak.js +12 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/component.js +214 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/el.js +13 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/html.js +30 -34
- data/vendor/assets/javascripts/bower/vue/src/directives/if.js +77 -46
- data/vendor/assets/javascripts/bower/vue/src/directives/index.js +22 -129
- data/vendor/assets/javascripts/bower/vue/src/directives/model/checkbox.js +25 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/model/default.js +123 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/model/index.js +56 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/model/radio.js +26 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/model/select.js +166 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/on.js +51 -50
- data/vendor/assets/javascripts/bower/vue/src/directives/partial.js +36 -42
- data/vendor/assets/javascripts/bower/vue/src/directives/ref.js +24 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/repeat.js +477 -226
- data/vendor/assets/javascripts/bower/vue/src/directives/show.js +8 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/style.js +49 -37
- data/vendor/assets/javascripts/bower/vue/src/directives/text.js +15 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/transition.js +12 -0
- data/vendor/assets/javascripts/bower/vue/src/directives/with.js +38 -41
- data/vendor/assets/javascripts/bower/vue/src/filters/array-filters.js +87 -0
- data/vendor/assets/javascripts/bower/vue/src/filters/index.js +135 -0
- data/vendor/assets/javascripts/bower/vue/src/instance/compile.js +71 -0
- data/vendor/assets/javascripts/bower/vue/src/instance/events.js +122 -0
- data/vendor/assets/javascripts/bower/vue/src/instance/init.js +76 -0
- data/vendor/assets/javascripts/bower/vue/src/instance/scope.js +217 -0
- data/vendor/assets/javascripts/bower/vue/src/observer/array.js +90 -0
- data/vendor/assets/javascripts/bower/vue/src/observer/dep.js +50 -0
- data/vendor/assets/javascripts/bower/vue/src/observer/index.js +235 -0
- data/vendor/assets/javascripts/bower/vue/src/observer/object.js +75 -0
- data/vendor/assets/javascripts/bower/vue/src/parsers/directive.js +159 -0
- data/vendor/assets/javascripts/bower/vue/src/parsers/expression.js +226 -0
- data/vendor/assets/javascripts/bower/vue/src/parsers/path.js +300 -0
- data/vendor/assets/javascripts/bower/vue/src/parsers/template.js +246 -0
- data/vendor/assets/javascripts/bower/vue/src/parsers/text.js +178 -0
- data/vendor/assets/javascripts/bower/vue/src/transition/css.js +189 -0
- data/vendor/assets/javascripts/bower/vue/src/transition/index.js +151 -0
- data/vendor/assets/javascripts/bower/vue/src/transition/js.js +43 -0
- data/vendor/assets/javascripts/bower/vue/src/util/debug.js +50 -0
- data/vendor/assets/javascripts/bower/vue/src/util/dom.js +176 -0
- data/vendor/assets/javascripts/bower/vue/src/util/env.js +74 -0
- data/vendor/assets/javascripts/bower/vue/src/util/filter.js +72 -0
- data/vendor/assets/javascripts/bower/vue/src/util/index.js +8 -0
- data/vendor/assets/javascripts/bower/vue/src/util/lang.js +175 -0
- data/vendor/assets/javascripts/bower/vue/src/util/merge-option.js +258 -0
- data/vendor/assets/javascripts/bower/vue/src/vue.js +84 -0
- data/vendor/assets/javascripts/bower/vue/src/watcher.js +240 -0
- metadata +65 -20
- data/app/assets/javascripts/setting_format.js +0 -15
- data/vendor/assets/javascripts/bower/vue/src/binding.js +0 -103
- data/vendor/assets/javascripts/bower/vue/src/compiler.js +0 -1037
- data/vendor/assets/javascripts/bower/vue/src/deps-parser.js +0 -65
- data/vendor/assets/javascripts/bower/vue/src/directives/model.js +0 -174
- data/vendor/assets/javascripts/bower/vue/src/directives/view.js +0 -56
- data/vendor/assets/javascripts/bower/vue/src/emitter.js +0 -97
- data/vendor/assets/javascripts/bower/vue/src/exp-parser.js +0 -190
- data/vendor/assets/javascripts/bower/vue/src/filters.js +0 -191
- data/vendor/assets/javascripts/bower/vue/src/fragment.js +0 -67
- data/vendor/assets/javascripts/bower/vue/src/main.js +0 -188
- data/vendor/assets/javascripts/bower/vue/src/observer.js +0 -446
- data/vendor/assets/javascripts/bower/vue/src/template-parser.js +0 -46
- data/vendor/assets/javascripts/bower/vue/src/text-parser.js +0 -96
- data/vendor/assets/javascripts/bower/vue/src/transition.js +0 -228
- data/vendor/assets/javascripts/bower/vue/src/utils.js +0 -326
- data/vendor/assets/javascripts/bower/vue/src/viewmodel.js +0 -190
@@ -1,65 +0,0 @@
|
|
1
|
-
var Emitter = require('./emitter'),
|
2
|
-
utils = require('./utils'),
|
3
|
-
Observer = require('./observer'),
|
4
|
-
catcher = new Emitter()
|
5
|
-
|
6
|
-
/**
|
7
|
-
* Auto-extract the dependencies of a computed property
|
8
|
-
* by recording the getters triggered when evaluating it.
|
9
|
-
*/
|
10
|
-
function catchDeps (binding) {
|
11
|
-
if (binding.isFn) return
|
12
|
-
utils.log('\n- ' + binding.key)
|
13
|
-
var got = utils.hash()
|
14
|
-
binding.deps = []
|
15
|
-
catcher.on('get', function (dep) {
|
16
|
-
var has = got[dep.key]
|
17
|
-
if (
|
18
|
-
// avoid duplicate bindings
|
19
|
-
(has && has.compiler === dep.compiler) ||
|
20
|
-
// avoid repeated items as dependency
|
21
|
-
// only when the binding is from self or the parent chain
|
22
|
-
(dep.compiler.repeat && !isParentOf(dep.compiler, binding.compiler))
|
23
|
-
) {
|
24
|
-
return
|
25
|
-
}
|
26
|
-
got[dep.key] = dep
|
27
|
-
utils.log(' - ' + dep.key)
|
28
|
-
binding.deps.push(dep)
|
29
|
-
dep.subs.push(binding)
|
30
|
-
})
|
31
|
-
binding.value.$get()
|
32
|
-
catcher.off('get')
|
33
|
-
}
|
34
|
-
|
35
|
-
/**
|
36
|
-
* Test if A is a parent of or equals B
|
37
|
-
*/
|
38
|
-
function isParentOf (a, b) {
|
39
|
-
while (b) {
|
40
|
-
if (a === b) {
|
41
|
-
return true
|
42
|
-
}
|
43
|
-
b = b.parent
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
module.exports = {
|
48
|
-
|
49
|
-
/**
|
50
|
-
* the observer that catches events triggered by getters
|
51
|
-
*/
|
52
|
-
catcher: catcher,
|
53
|
-
|
54
|
-
/**
|
55
|
-
* parse a list of computed property bindings
|
56
|
-
*/
|
57
|
-
parse: function (bindings) {
|
58
|
-
utils.log('\nparsing dependencies...')
|
59
|
-
Observer.shouldGet = true
|
60
|
-
bindings.forEach(catchDeps)
|
61
|
-
Observer.shouldGet = false
|
62
|
-
utils.log('\ndone.')
|
63
|
-
}
|
64
|
-
|
65
|
-
}
|
@@ -1,174 +0,0 @@
|
|
1
|
-
var utils = require('../utils'),
|
2
|
-
isIE9 = navigator.userAgent.indexOf('MSIE 9.0') > 0,
|
3
|
-
filter = [].filter
|
4
|
-
|
5
|
-
/**
|
6
|
-
* Returns an array of values from a multiple select
|
7
|
-
*/
|
8
|
-
function getMultipleSelectOptions (select) {
|
9
|
-
return filter
|
10
|
-
.call(select.options, function (option) {
|
11
|
-
return option.selected
|
12
|
-
})
|
13
|
-
.map(function (option) {
|
14
|
-
return option.value || option.text
|
15
|
-
})
|
16
|
-
}
|
17
|
-
|
18
|
-
/**
|
19
|
-
* Two-way binding for form input elements
|
20
|
-
*/
|
21
|
-
module.exports = {
|
22
|
-
|
23
|
-
bind: function () {
|
24
|
-
|
25
|
-
var self = this,
|
26
|
-
el = self.el,
|
27
|
-
type = el.type,
|
28
|
-
tag = el.tagName
|
29
|
-
|
30
|
-
self.lock = false
|
31
|
-
self.ownerVM = self.binding.compiler.vm
|
32
|
-
|
33
|
-
// determine what event to listen to
|
34
|
-
self.event =
|
35
|
-
(self.compiler.options.lazy ||
|
36
|
-
tag === 'SELECT' ||
|
37
|
-
type === 'checkbox' || type === 'radio')
|
38
|
-
? 'change'
|
39
|
-
: 'input'
|
40
|
-
|
41
|
-
// determine the attribute to change when updating
|
42
|
-
self.attr = type === 'checkbox'
|
43
|
-
? 'checked'
|
44
|
-
: (tag === 'INPUT' || tag === 'SELECT' || tag === 'TEXTAREA')
|
45
|
-
? 'value'
|
46
|
-
: 'innerHTML'
|
47
|
-
|
48
|
-
// select[multiple] support
|
49
|
-
if(tag === 'SELECT' && el.hasAttribute('multiple')) {
|
50
|
-
this.multi = true
|
51
|
-
}
|
52
|
-
|
53
|
-
var compositionLock = false
|
54
|
-
self.cLock = function () {
|
55
|
-
compositionLock = true
|
56
|
-
}
|
57
|
-
self.cUnlock = function () {
|
58
|
-
compositionLock = false
|
59
|
-
}
|
60
|
-
el.addEventListener('compositionstart', this.cLock)
|
61
|
-
el.addEventListener('compositionend', this.cUnlock)
|
62
|
-
|
63
|
-
// attach listener
|
64
|
-
self.set = self.filters
|
65
|
-
? function () {
|
66
|
-
if (compositionLock) return
|
67
|
-
// if this directive has filters
|
68
|
-
// we need to let the vm.$set trigger
|
69
|
-
// update() so filters are applied.
|
70
|
-
// therefore we have to record cursor position
|
71
|
-
// so that after vm.$set changes the input
|
72
|
-
// value we can put the cursor back at where it is
|
73
|
-
var cursorPos
|
74
|
-
try { cursorPos = el.selectionStart } catch (e) {}
|
75
|
-
|
76
|
-
self._set()
|
77
|
-
|
78
|
-
// since updates are async
|
79
|
-
// we need to reset cursor position async too
|
80
|
-
utils.nextTick(function () {
|
81
|
-
if (cursorPos !== undefined) {
|
82
|
-
el.setSelectionRange(cursorPos, cursorPos)
|
83
|
-
}
|
84
|
-
})
|
85
|
-
}
|
86
|
-
: function () {
|
87
|
-
if (compositionLock) return
|
88
|
-
// no filters, don't let it trigger update()
|
89
|
-
self.lock = true
|
90
|
-
|
91
|
-
self._set()
|
92
|
-
|
93
|
-
utils.nextTick(function () {
|
94
|
-
self.lock = false
|
95
|
-
})
|
96
|
-
}
|
97
|
-
el.addEventListener(self.event, self.set)
|
98
|
-
|
99
|
-
// fix shit for IE9
|
100
|
-
// since it doesn't fire input on backspace / del / cut
|
101
|
-
if (isIE9) {
|
102
|
-
self.onCut = function () {
|
103
|
-
// cut event fires before the value actually changes
|
104
|
-
utils.nextTick(function () {
|
105
|
-
self.set()
|
106
|
-
})
|
107
|
-
}
|
108
|
-
self.onDel = function (e) {
|
109
|
-
if (e.keyCode === 46 || e.keyCode === 8) {
|
110
|
-
self.set()
|
111
|
-
}
|
112
|
-
}
|
113
|
-
el.addEventListener('cut', self.onCut)
|
114
|
-
el.addEventListener('keyup', self.onDel)
|
115
|
-
}
|
116
|
-
},
|
117
|
-
|
118
|
-
_set: function () {
|
119
|
-
this.ownerVM.$set(
|
120
|
-
this.key, this.multi
|
121
|
-
? getMultipleSelectOptions(this.el)
|
122
|
-
: this.el[this.attr]
|
123
|
-
)
|
124
|
-
},
|
125
|
-
|
126
|
-
update: function (value, init) {
|
127
|
-
/* jshint eqeqeq: false */
|
128
|
-
// sync back inline value if initial data is undefined
|
129
|
-
if (init && value === undefined) {
|
130
|
-
return this._set()
|
131
|
-
}
|
132
|
-
if (this.lock) return
|
133
|
-
var el = this.el
|
134
|
-
if (el.tagName === 'SELECT') { // select dropdown
|
135
|
-
el.selectedIndex = -1
|
136
|
-
if(this.multi && Array.isArray(value)) {
|
137
|
-
value.forEach(this.updateSelect, this)
|
138
|
-
} else {
|
139
|
-
this.updateSelect(value)
|
140
|
-
}
|
141
|
-
} else if (el.type === 'radio') { // radio button
|
142
|
-
el.checked = value == el.value
|
143
|
-
} else if (el.type === 'checkbox') { // checkbox
|
144
|
-
el.checked = !!value
|
145
|
-
} else {
|
146
|
-
el[this.attr] = utils.guard(value)
|
147
|
-
}
|
148
|
-
},
|
149
|
-
|
150
|
-
updateSelect: function (value) {
|
151
|
-
/* jshint eqeqeq: false */
|
152
|
-
// setting <select>'s value in IE9 doesn't work
|
153
|
-
// we have to manually loop through the options
|
154
|
-
var options = this.el.options,
|
155
|
-
i = options.length
|
156
|
-
while (i--) {
|
157
|
-
if (options[i].value == value) {
|
158
|
-
options[i].selected = true
|
159
|
-
break
|
160
|
-
}
|
161
|
-
}
|
162
|
-
},
|
163
|
-
|
164
|
-
unbind: function () {
|
165
|
-
var el = this.el
|
166
|
-
el.removeEventListener(this.event, this.set)
|
167
|
-
el.removeEventListener('compositionstart', this.cLock)
|
168
|
-
el.removeEventListener('compositionend', this.cUnlock)
|
169
|
-
if (isIE9) {
|
170
|
-
el.removeEventListener('cut', this.onCut)
|
171
|
-
el.removeEventListener('keyup', this.onDel)
|
172
|
-
}
|
173
|
-
}
|
174
|
-
}
|
@@ -1,56 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Manages a conditional child VM using the
|
3
|
-
* binding's value as the component ID.
|
4
|
-
*/
|
5
|
-
module.exports = {
|
6
|
-
|
7
|
-
bind: function () {
|
8
|
-
|
9
|
-
// track position in DOM with a ref node
|
10
|
-
var el = this.raw = this.el,
|
11
|
-
parent = el.parentNode,
|
12
|
-
ref = this.ref = document.createComment('v-view')
|
13
|
-
parent.insertBefore(ref, el)
|
14
|
-
parent.removeChild(el)
|
15
|
-
|
16
|
-
// cache original content
|
17
|
-
/* jshint boss: true */
|
18
|
-
var node,
|
19
|
-
frag = this.inner = document.createElement('div')
|
20
|
-
while (node = el.firstChild) {
|
21
|
-
frag.appendChild(node)
|
22
|
-
}
|
23
|
-
|
24
|
-
},
|
25
|
-
|
26
|
-
update: function(value) {
|
27
|
-
|
28
|
-
this.unbind()
|
29
|
-
|
30
|
-
var Ctor = this.compiler.getOption('components', value)
|
31
|
-
if (!Ctor) return
|
32
|
-
|
33
|
-
this.childVM = new Ctor({
|
34
|
-
el: this.raw.cloneNode(true),
|
35
|
-
parent: this.vm,
|
36
|
-
compilerOptions: {
|
37
|
-
rawContent: this.inner.cloneNode(true)
|
38
|
-
}
|
39
|
-
})
|
40
|
-
|
41
|
-
this.el = this.childVM.$el
|
42
|
-
if (this.compiler.init) {
|
43
|
-
this.ref.parentNode.insertBefore(this.el, this.ref)
|
44
|
-
} else {
|
45
|
-
this.childVM.$before(this.ref)
|
46
|
-
}
|
47
|
-
|
48
|
-
},
|
49
|
-
|
50
|
-
unbind: function() {
|
51
|
-
if (this.childVM) {
|
52
|
-
this.childVM.$destroy()
|
53
|
-
}
|
54
|
-
}
|
55
|
-
|
56
|
-
}
|
@@ -1,97 +0,0 @@
|
|
1
|
-
var slice = [].slice
|
2
|
-
|
3
|
-
function Emitter (ctx) {
|
4
|
-
this._ctx = ctx || this
|
5
|
-
}
|
6
|
-
|
7
|
-
var EmitterProto = Emitter.prototype
|
8
|
-
|
9
|
-
EmitterProto.on = function (event, fn) {
|
10
|
-
this._cbs = this._cbs || {}
|
11
|
-
;(this._cbs[event] = this._cbs[event] || [])
|
12
|
-
.push(fn)
|
13
|
-
return this
|
14
|
-
}
|
15
|
-
|
16
|
-
EmitterProto.once = function (event, fn) {
|
17
|
-
var self = this
|
18
|
-
this._cbs = this._cbs || {}
|
19
|
-
|
20
|
-
function on () {
|
21
|
-
self.off(event, on)
|
22
|
-
fn.apply(this, arguments)
|
23
|
-
}
|
24
|
-
|
25
|
-
on.fn = fn
|
26
|
-
this.on(event, on)
|
27
|
-
return this
|
28
|
-
}
|
29
|
-
|
30
|
-
EmitterProto.off = function (event, fn) {
|
31
|
-
this._cbs = this._cbs || {}
|
32
|
-
|
33
|
-
// all
|
34
|
-
if (!arguments.length) {
|
35
|
-
this._cbs = {}
|
36
|
-
return this
|
37
|
-
}
|
38
|
-
|
39
|
-
// specific event
|
40
|
-
var callbacks = this._cbs[event]
|
41
|
-
if (!callbacks) return this
|
42
|
-
|
43
|
-
// remove all handlers
|
44
|
-
if (arguments.length === 1) {
|
45
|
-
delete this._cbs[event]
|
46
|
-
return this
|
47
|
-
}
|
48
|
-
|
49
|
-
// remove specific handler
|
50
|
-
var cb
|
51
|
-
for (var i = 0; i < callbacks.length; i++) {
|
52
|
-
cb = callbacks[i]
|
53
|
-
if (cb === fn || cb.fn === fn) {
|
54
|
-
callbacks.splice(i, 1)
|
55
|
-
break
|
56
|
-
}
|
57
|
-
}
|
58
|
-
return this
|
59
|
-
}
|
60
|
-
|
61
|
-
/**
|
62
|
-
* The internal, faster emit with fixed amount of arguments
|
63
|
-
* using Function.call
|
64
|
-
*/
|
65
|
-
EmitterProto.emit = function (event, a, b, c) {
|
66
|
-
this._cbs = this._cbs || {}
|
67
|
-
var callbacks = this._cbs[event]
|
68
|
-
|
69
|
-
if (callbacks) {
|
70
|
-
callbacks = callbacks.slice(0)
|
71
|
-
for (var i = 0, len = callbacks.length; i < len; i++) {
|
72
|
-
callbacks[i].call(this._ctx, a, b, c)
|
73
|
-
}
|
74
|
-
}
|
75
|
-
|
76
|
-
return this
|
77
|
-
}
|
78
|
-
|
79
|
-
/**
|
80
|
-
* The external emit using Function.apply
|
81
|
-
*/
|
82
|
-
EmitterProto.applyEmit = function (event) {
|
83
|
-
this._cbs = this._cbs || {}
|
84
|
-
var callbacks = this._cbs[event], args
|
85
|
-
|
86
|
-
if (callbacks) {
|
87
|
-
callbacks = callbacks.slice(0)
|
88
|
-
args = slice.call(arguments, 1)
|
89
|
-
for (var i = 0, len = callbacks.length; i < len; i++) {
|
90
|
-
callbacks[i].apply(this._ctx, args)
|
91
|
-
}
|
92
|
-
}
|
93
|
-
|
94
|
-
return this
|
95
|
-
}
|
96
|
-
|
97
|
-
module.exports = Emitter
|
@@ -1,190 +0,0 @@
|
|
1
|
-
var utils = require('./utils'),
|
2
|
-
STR_SAVE_RE = /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,
|
3
|
-
STR_RESTORE_RE = /"(\d+)"/g,
|
4
|
-
NEWLINE_RE = /\n/g,
|
5
|
-
CTOR_RE = new RegExp('constructor'.split('').join('[\'"+, ]*')),
|
6
|
-
UNICODE_RE = /\\u\d\d\d\d/
|
7
|
-
|
8
|
-
// Variable extraction scooped from https://github.com/RubyLouvre/avalon
|
9
|
-
|
10
|
-
var KEYWORDS =
|
11
|
-
// keywords
|
12
|
-
'break,case,catch,continue,debugger,default,delete,do,else,false' +
|
13
|
-
',finally,for,function,if,in,instanceof,new,null,return,switch,this' +
|
14
|
-
',throw,true,try,typeof,var,void,while,with,undefined' +
|
15
|
-
// reserved
|
16
|
-
',abstract,boolean,byte,char,class,const,double,enum,export,extends' +
|
17
|
-
',final,float,goto,implements,import,int,interface,long,native' +
|
18
|
-
',package,private,protected,public,short,static,super,synchronized' +
|
19
|
-
',throws,transient,volatile' +
|
20
|
-
// ECMA 5 - use strict
|
21
|
-
',arguments,let,yield' +
|
22
|
-
// allow using Math in expressions
|
23
|
-
',Math',
|
24
|
-
|
25
|
-
KEYWORDS_RE = new RegExp(["\\b" + KEYWORDS.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g'),
|
26
|
-
REMOVE_RE = /\/\*(?:.|\n)*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|'[^']*'|"[^"]*"|[\s\t\n]*\.[\s\t\n]*[$\w\.]+|[\{,]\s*[\w\$_]+\s*:/g,
|
27
|
-
SPLIT_RE = /[^\w$]+/g,
|
28
|
-
NUMBER_RE = /\b\d[^,]*/g,
|
29
|
-
BOUNDARY_RE = /^,+|,+$/g
|
30
|
-
|
31
|
-
/**
|
32
|
-
* Strip top level variable names from a snippet of JS expression
|
33
|
-
*/
|
34
|
-
function getVariables (code) {
|
35
|
-
code = code
|
36
|
-
.replace(REMOVE_RE, '')
|
37
|
-
.replace(SPLIT_RE, ',')
|
38
|
-
.replace(KEYWORDS_RE, '')
|
39
|
-
.replace(NUMBER_RE, '')
|
40
|
-
.replace(BOUNDARY_RE, '')
|
41
|
-
return code
|
42
|
-
? code.split(/,+/)
|
43
|
-
: []
|
44
|
-
}
|
45
|
-
|
46
|
-
/**
|
47
|
-
* A given path could potentially exist not on the
|
48
|
-
* current compiler, but up in the parent chain somewhere.
|
49
|
-
* This function generates an access relationship string
|
50
|
-
* that can be used in the getter function by walking up
|
51
|
-
* the parent chain to check for key existence.
|
52
|
-
*
|
53
|
-
* It stops at top parent if no vm in the chain has the
|
54
|
-
* key. It then creates any missing bindings on the
|
55
|
-
* final resolved vm.
|
56
|
-
*/
|
57
|
-
function traceScope (path, compiler, data) {
|
58
|
-
var rel = '',
|
59
|
-
dist = 0,
|
60
|
-
self = compiler
|
61
|
-
|
62
|
-
if (data && utils.get(data, path) !== undefined) {
|
63
|
-
// hack: temporarily attached data
|
64
|
-
return '$temp.'
|
65
|
-
}
|
66
|
-
|
67
|
-
while (compiler) {
|
68
|
-
if (compiler.hasKey(path)) {
|
69
|
-
break
|
70
|
-
} else {
|
71
|
-
compiler = compiler.parent
|
72
|
-
dist++
|
73
|
-
}
|
74
|
-
}
|
75
|
-
if (compiler) {
|
76
|
-
while (dist--) {
|
77
|
-
rel += '$parent.'
|
78
|
-
}
|
79
|
-
if (!compiler.bindings[path] && path.charAt(0) !== '$') {
|
80
|
-
compiler.createBinding(path)
|
81
|
-
}
|
82
|
-
} else {
|
83
|
-
self.createBinding(path)
|
84
|
-
}
|
85
|
-
return rel
|
86
|
-
}
|
87
|
-
|
88
|
-
/**
|
89
|
-
* Create a function from a string...
|
90
|
-
* this looks like evil magic but since all variables are limited
|
91
|
-
* to the VM's data it's actually properly sandboxed
|
92
|
-
*/
|
93
|
-
function makeGetter (exp, raw) {
|
94
|
-
var fn
|
95
|
-
try {
|
96
|
-
fn = new Function(exp)
|
97
|
-
} catch (e) {
|
98
|
-
utils.warn('Error parsing expression: ' + raw)
|
99
|
-
}
|
100
|
-
return fn
|
101
|
-
}
|
102
|
-
|
103
|
-
/**
|
104
|
-
* Escape a leading dollar sign for regex construction
|
105
|
-
*/
|
106
|
-
function escapeDollar (v) {
|
107
|
-
return v.charAt(0) === '$'
|
108
|
-
? '\\' + v
|
109
|
-
: v
|
110
|
-
}
|
111
|
-
|
112
|
-
/**
|
113
|
-
* Parse and return an anonymous computed property getter function
|
114
|
-
* from an arbitrary expression, together with a list of paths to be
|
115
|
-
* created as bindings.
|
116
|
-
*/
|
117
|
-
exports.parse = function (exp, compiler, data) {
|
118
|
-
// unicode and 'constructor' are not allowed for XSS security.
|
119
|
-
if (UNICODE_RE.test(exp) || CTOR_RE.test(exp)) {
|
120
|
-
utils.warn('Unsafe expression: ' + exp)
|
121
|
-
return
|
122
|
-
}
|
123
|
-
// extract variable names
|
124
|
-
var vars = getVariables(exp)
|
125
|
-
if (!vars.length) {
|
126
|
-
return makeGetter('return ' + exp, exp)
|
127
|
-
}
|
128
|
-
vars = utils.unique(vars)
|
129
|
-
|
130
|
-
var accessors = '',
|
131
|
-
has = utils.hash(),
|
132
|
-
strings = [],
|
133
|
-
// construct a regex to extract all valid variable paths
|
134
|
-
// ones that begin with "$" are particularly tricky
|
135
|
-
// because we can't use \b for them
|
136
|
-
pathRE = new RegExp(
|
137
|
-
"[^$\\w\\.](" +
|
138
|
-
vars.map(escapeDollar).join('|') +
|
139
|
-
")[$\\w\\.]*\\b", 'g'
|
140
|
-
),
|
141
|
-
body = (' ' + exp)
|
142
|
-
.replace(STR_SAVE_RE, saveStrings)
|
143
|
-
.replace(pathRE, replacePath)
|
144
|
-
.replace(STR_RESTORE_RE, restoreStrings)
|
145
|
-
|
146
|
-
body = accessors + 'return ' + body
|
147
|
-
|
148
|
-
function saveStrings (str) {
|
149
|
-
var i = strings.length
|
150
|
-
// escape newlines in strings so the expression
|
151
|
-
// can be correctly evaluated
|
152
|
-
strings[i] = str.replace(NEWLINE_RE, '\\n')
|
153
|
-
return '"' + i + '"'
|
154
|
-
}
|
155
|
-
|
156
|
-
function replacePath (path) {
|
157
|
-
// keep track of the first char
|
158
|
-
var c = path.charAt(0)
|
159
|
-
path = path.slice(1)
|
160
|
-
var val = 'this.' + traceScope(path, compiler, data) + path
|
161
|
-
if (!has[path]) {
|
162
|
-
accessors += val + ';'
|
163
|
-
has[path] = 1
|
164
|
-
}
|
165
|
-
// don't forget to put that first char back
|
166
|
-
return c + val
|
167
|
-
}
|
168
|
-
|
169
|
-
function restoreStrings (str, i) {
|
170
|
-
return strings[i]
|
171
|
-
}
|
172
|
-
|
173
|
-
return makeGetter(body, exp)
|
174
|
-
}
|
175
|
-
|
176
|
-
/**
|
177
|
-
* Evaluate an expression in the context of a compiler.
|
178
|
-
* Accepts additional data.
|
179
|
-
*/
|
180
|
-
exports.eval = function (exp, compiler, data) {
|
181
|
-
var getter = exports.parse(exp, compiler, data), res
|
182
|
-
if (getter) {
|
183
|
-
// hack: temporarily attach the additional data so
|
184
|
-
// it can be accessed in the getter
|
185
|
-
compiler.vm.$temp = data
|
186
|
-
res = getter.call(compiler.vm)
|
187
|
-
delete compiler.vm.$temp
|
188
|
-
}
|
189
|
-
return res
|
190
|
-
}
|