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
@@ -0,0 +1,246 @@
|
|
1
|
+
var _ = require('../util')
|
2
|
+
var Cache = require('../cache')
|
3
|
+
var templateCache = new Cache(100)
|
4
|
+
|
5
|
+
var map = {
|
6
|
+
_default : [0, '', ''],
|
7
|
+
legend : [1, '<fieldset>', '</fieldset>'],
|
8
|
+
tr : [2, '<table><tbody>', '</tbody></table>'],
|
9
|
+
col : [
|
10
|
+
2,
|
11
|
+
'<table><tbody></tbody><colgroup>',
|
12
|
+
'</colgroup></table>'
|
13
|
+
]
|
14
|
+
}
|
15
|
+
|
16
|
+
map.td =
|
17
|
+
map.th = [
|
18
|
+
3,
|
19
|
+
'<table><tbody><tr>',
|
20
|
+
'</tr></tbody></table>'
|
21
|
+
]
|
22
|
+
|
23
|
+
map.option =
|
24
|
+
map.optgroup = [
|
25
|
+
1,
|
26
|
+
'<select multiple="multiple">',
|
27
|
+
'</select>'
|
28
|
+
]
|
29
|
+
|
30
|
+
map.thead =
|
31
|
+
map.tbody =
|
32
|
+
map.colgroup =
|
33
|
+
map.caption =
|
34
|
+
map.tfoot = [1, '<table>', '</table>']
|
35
|
+
|
36
|
+
map.g =
|
37
|
+
map.defs =
|
38
|
+
map.symbol =
|
39
|
+
map.use =
|
40
|
+
map.image =
|
41
|
+
map.text =
|
42
|
+
map.circle =
|
43
|
+
map.ellipse =
|
44
|
+
map.line =
|
45
|
+
map.path =
|
46
|
+
map.polygon =
|
47
|
+
map.polyline =
|
48
|
+
map.rect = [
|
49
|
+
1,
|
50
|
+
'<svg ' +
|
51
|
+
'xmlns="http://www.w3.org/2000/svg" ' +
|
52
|
+
'xmlns:xlink="http://www.w3.org/1999/xlink" ' +
|
53
|
+
'xmlns:ev="http://www.w3.org/2001/xml-events"' +
|
54
|
+
'version="1.1">',
|
55
|
+
'</svg>'
|
56
|
+
]
|
57
|
+
|
58
|
+
var TAG_RE = /<([\w:]+)/
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Convert a string template to a DocumentFragment.
|
62
|
+
* Determines correct wrapping by tag types. Wrapping
|
63
|
+
* strategy found in jQuery & component/domify.
|
64
|
+
*
|
65
|
+
* @param {String} templateString
|
66
|
+
* @return {DocumentFragment}
|
67
|
+
*/
|
68
|
+
|
69
|
+
function stringToFragment (templateString) {
|
70
|
+
// try a cache hit first
|
71
|
+
var hit = templateCache.get(templateString)
|
72
|
+
if (hit) {
|
73
|
+
return hit
|
74
|
+
}
|
75
|
+
|
76
|
+
var frag = document.createDocumentFragment()
|
77
|
+
var tagMatch = TAG_RE.exec(templateString)
|
78
|
+
|
79
|
+
if (!tagMatch) {
|
80
|
+
// text only, return a single text node.
|
81
|
+
frag.appendChild(
|
82
|
+
document.createTextNode(templateString)
|
83
|
+
)
|
84
|
+
} else {
|
85
|
+
|
86
|
+
var tag = tagMatch[1]
|
87
|
+
var wrap = map[tag] || map._default
|
88
|
+
var depth = wrap[0]
|
89
|
+
var prefix = wrap[1]
|
90
|
+
var suffix = wrap[2]
|
91
|
+
var node = document.createElement('div')
|
92
|
+
|
93
|
+
node.innerHTML = prefix + templateString.trim() + suffix
|
94
|
+
while (depth--) {
|
95
|
+
node = node.lastChild
|
96
|
+
}
|
97
|
+
|
98
|
+
var child
|
99
|
+
/* jshint boss:true */
|
100
|
+
while (child = node.firstChild) {
|
101
|
+
frag.appendChild(child)
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
templateCache.put(templateString, frag)
|
106
|
+
return frag
|
107
|
+
}
|
108
|
+
|
109
|
+
/**
|
110
|
+
* Convert a template node to a DocumentFragment.
|
111
|
+
*
|
112
|
+
* @param {Node} node
|
113
|
+
* @return {DocumentFragment}
|
114
|
+
*/
|
115
|
+
|
116
|
+
function nodeToFragment (node) {
|
117
|
+
var tag = node.tagName
|
118
|
+
// if its a template tag and the browser supports it,
|
119
|
+
// its content is already a document fragment.
|
120
|
+
if (
|
121
|
+
tag === 'TEMPLATE' &&
|
122
|
+
node.content instanceof DocumentFragment
|
123
|
+
) {
|
124
|
+
return node.content
|
125
|
+
}
|
126
|
+
return tag === 'SCRIPT'
|
127
|
+
? stringToFragment(node.textContent)
|
128
|
+
: stringToFragment(node.innerHTML)
|
129
|
+
}
|
130
|
+
|
131
|
+
// Test for the presence of the Safari template cloning bug
|
132
|
+
// https://bugs.webkit.org/show_bug.cgi?id=137755
|
133
|
+
var hasBrokenTemplate = _.inBrowser
|
134
|
+
? (function () {
|
135
|
+
var a = document.createElement('div')
|
136
|
+
a.innerHTML = '<template>1</template>'
|
137
|
+
return !a.cloneNode(true).firstChild.innerHTML
|
138
|
+
})()
|
139
|
+
: false
|
140
|
+
|
141
|
+
// Test for IE10/11 textarea placeholder clone bug
|
142
|
+
var hasTextareaCloneBug = _.inBrowser
|
143
|
+
? (function () {
|
144
|
+
var t = document.createElement('textarea')
|
145
|
+
t.placeholder = 't'
|
146
|
+
return t.cloneNode(true).value === 't'
|
147
|
+
})()
|
148
|
+
: false
|
149
|
+
|
150
|
+
/**
|
151
|
+
* 1. Deal with Safari cloning nested <template> bug by
|
152
|
+
* manually cloning all template instances.
|
153
|
+
* 2. Deal with IE10/11 textarea placeholder bug by setting
|
154
|
+
* the correct value after cloning.
|
155
|
+
*
|
156
|
+
* @param {Element|DocumentFragment} node
|
157
|
+
* @return {Element|DocumentFragment}
|
158
|
+
*/
|
159
|
+
|
160
|
+
exports.clone = function (node) {
|
161
|
+
var res = node.cloneNode(true)
|
162
|
+
var i, original, cloned
|
163
|
+
/* istanbul ignore if */
|
164
|
+
if (hasBrokenTemplate) {
|
165
|
+
original = node.querySelectorAll('template')
|
166
|
+
if (original.length) {
|
167
|
+
cloned = res.querySelectorAll('template')
|
168
|
+
i = cloned.length
|
169
|
+
while (i--) {
|
170
|
+
cloned[i].parentNode.replaceChild(
|
171
|
+
original[i].cloneNode(true),
|
172
|
+
cloned[i]
|
173
|
+
)
|
174
|
+
}
|
175
|
+
}
|
176
|
+
}
|
177
|
+
/* istanbul ignore if */
|
178
|
+
if (hasTextareaCloneBug) {
|
179
|
+
if (node.tagName === 'TEXTAREA') {
|
180
|
+
res.value = node.value
|
181
|
+
} else {
|
182
|
+
original = node.querySelectorAll('textarea')
|
183
|
+
if (original.length) {
|
184
|
+
cloned = res.querySelectorAll('textarea')
|
185
|
+
i = cloned.length
|
186
|
+
while (i--) {
|
187
|
+
cloned[i].value = original[i].value
|
188
|
+
}
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
return res
|
193
|
+
}
|
194
|
+
|
195
|
+
/**
|
196
|
+
* Process the template option and normalizes it into a
|
197
|
+
* a DocumentFragment that can be used as a partial or a
|
198
|
+
* instance template.
|
199
|
+
*
|
200
|
+
* @param {*} template
|
201
|
+
* Possible values include:
|
202
|
+
* - DocumentFragment object
|
203
|
+
* - Node object of type Template
|
204
|
+
* - id selector: '#some-template-id'
|
205
|
+
* - template string: '<div><span>{{msg}}</span></div>'
|
206
|
+
* @param {Boolean} clone
|
207
|
+
* @return {DocumentFragment|undefined}
|
208
|
+
*/
|
209
|
+
|
210
|
+
exports.parse = function (template, clone) {
|
211
|
+
var node, frag
|
212
|
+
|
213
|
+
// if the template is already a document fragment,
|
214
|
+
// do nothing
|
215
|
+
if (template instanceof DocumentFragment) {
|
216
|
+
return clone
|
217
|
+
? template.cloneNode(true)
|
218
|
+
: template
|
219
|
+
}
|
220
|
+
|
221
|
+
if (typeof template === 'string') {
|
222
|
+
// id selector
|
223
|
+
if (template.charAt(0) === '#') {
|
224
|
+
// id selector can be cached too
|
225
|
+
frag = templateCache.get(template)
|
226
|
+
if (!frag) {
|
227
|
+
node = document.getElementById(template.slice(1))
|
228
|
+
if (node) {
|
229
|
+
frag = nodeToFragment(node)
|
230
|
+
// save selector to cache
|
231
|
+
templateCache.put(template, frag)
|
232
|
+
}
|
233
|
+
}
|
234
|
+
} else {
|
235
|
+
// normal string template
|
236
|
+
frag = stringToFragment(template)
|
237
|
+
}
|
238
|
+
} else if (template.nodeType) {
|
239
|
+
// a direct node
|
240
|
+
frag = nodeToFragment(template)
|
241
|
+
}
|
242
|
+
|
243
|
+
return frag && clone
|
244
|
+
? exports.clone(frag)
|
245
|
+
: frag
|
246
|
+
}
|
@@ -0,0 +1,178 @@
|
|
1
|
+
var Cache = require('../cache')
|
2
|
+
var config = require('../config')
|
3
|
+
var dirParser = require('./directive')
|
4
|
+
var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g
|
5
|
+
var cache, tagRE, htmlRE, firstChar, lastChar
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Escape a string so it can be used in a RegExp
|
9
|
+
* constructor.
|
10
|
+
*
|
11
|
+
* @param {String} str
|
12
|
+
*/
|
13
|
+
|
14
|
+
function escapeRegex (str) {
|
15
|
+
return str.replace(regexEscapeRE, '\\$&')
|
16
|
+
}
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Compile the interpolation tag regex.
|
20
|
+
*
|
21
|
+
* @return {RegExp}
|
22
|
+
*/
|
23
|
+
|
24
|
+
function compileRegex () {
|
25
|
+
config._delimitersChanged = false
|
26
|
+
var open = config.delimiters[0]
|
27
|
+
var close = config.delimiters[1]
|
28
|
+
firstChar = open.charAt(0)
|
29
|
+
lastChar = close.charAt(close.length - 1)
|
30
|
+
var firstCharRE = escapeRegex(firstChar)
|
31
|
+
var lastCharRE = escapeRegex(lastChar)
|
32
|
+
var openRE = escapeRegex(open)
|
33
|
+
var closeRE = escapeRegex(close)
|
34
|
+
tagRE = new RegExp(
|
35
|
+
firstCharRE + '?' + openRE +
|
36
|
+
'(.+?)' +
|
37
|
+
closeRE + lastCharRE + '?',
|
38
|
+
'g'
|
39
|
+
)
|
40
|
+
htmlRE = new RegExp(
|
41
|
+
'^' + firstCharRE + openRE +
|
42
|
+
'.*' +
|
43
|
+
closeRE + lastCharRE + '$'
|
44
|
+
)
|
45
|
+
// reset cache
|
46
|
+
cache = new Cache(1000)
|
47
|
+
}
|
48
|
+
|
49
|
+
/**
|
50
|
+
* Parse a template text string into an array of tokens.
|
51
|
+
*
|
52
|
+
* @param {String} text
|
53
|
+
* @return {Array<Object> | null}
|
54
|
+
* - {String} type
|
55
|
+
* - {String} value
|
56
|
+
* - {Boolean} [html]
|
57
|
+
* - {Boolean} [oneTime]
|
58
|
+
*/
|
59
|
+
|
60
|
+
exports.parse = function (text) {
|
61
|
+
if (config._delimitersChanged) {
|
62
|
+
compileRegex()
|
63
|
+
}
|
64
|
+
var hit = cache.get(text)
|
65
|
+
if (hit) {
|
66
|
+
return hit
|
67
|
+
}
|
68
|
+
if (!tagRE.test(text)) {
|
69
|
+
return null
|
70
|
+
}
|
71
|
+
var tokens = []
|
72
|
+
var lastIndex = tagRE.lastIndex = 0
|
73
|
+
var match, index, value, first, oneTime, partial
|
74
|
+
/* jshint boss:true */
|
75
|
+
while (match = tagRE.exec(text)) {
|
76
|
+
index = match.index
|
77
|
+
// push text token
|
78
|
+
if (index > lastIndex) {
|
79
|
+
tokens.push({
|
80
|
+
value: text.slice(lastIndex, index)
|
81
|
+
})
|
82
|
+
}
|
83
|
+
// tag token
|
84
|
+
first = match[1].charCodeAt(0)
|
85
|
+
oneTime = first === 0x2A // *
|
86
|
+
partial = first === 0x3E // >
|
87
|
+
value = (oneTime || partial)
|
88
|
+
? match[1].slice(1)
|
89
|
+
: match[1]
|
90
|
+
tokens.push({
|
91
|
+
tag: true,
|
92
|
+
value: value.trim(),
|
93
|
+
html: htmlRE.test(match[0]),
|
94
|
+
oneTime: oneTime,
|
95
|
+
partial: partial
|
96
|
+
})
|
97
|
+
lastIndex = index + match[0].length
|
98
|
+
}
|
99
|
+
if (lastIndex < text.length) {
|
100
|
+
tokens.push({
|
101
|
+
value: text.slice(lastIndex)
|
102
|
+
})
|
103
|
+
}
|
104
|
+
cache.put(text, tokens)
|
105
|
+
return tokens
|
106
|
+
}
|
107
|
+
|
108
|
+
/**
|
109
|
+
* Format a list of tokens into an expression.
|
110
|
+
* e.g. tokens parsed from 'a {{b}} c' can be serialized
|
111
|
+
* into one single expression as '"a " + b + " c"'.
|
112
|
+
*
|
113
|
+
* @param {Array} tokens
|
114
|
+
* @param {Vue} [vm]
|
115
|
+
* @return {String}
|
116
|
+
*/
|
117
|
+
|
118
|
+
exports.tokensToExp = function (tokens, vm) {
|
119
|
+
return tokens.length > 1
|
120
|
+
? tokens.map(function (token) {
|
121
|
+
return formatToken(token, vm)
|
122
|
+
}).join('+')
|
123
|
+
: formatToken(tokens[0], vm, true)
|
124
|
+
}
|
125
|
+
|
126
|
+
/**
|
127
|
+
* Format a single token.
|
128
|
+
*
|
129
|
+
* @param {Object} token
|
130
|
+
* @param {Vue} [vm]
|
131
|
+
* @param {Boolean} single
|
132
|
+
* @return {String}
|
133
|
+
*/
|
134
|
+
|
135
|
+
function formatToken (token, vm, single) {
|
136
|
+
return token.tag
|
137
|
+
? vm && token.oneTime
|
138
|
+
? '"' + vm.$eval(token.value) + '"'
|
139
|
+
: single
|
140
|
+
? token.value
|
141
|
+
: inlineFilters(token.value)
|
142
|
+
: '"' + token.value + '"'
|
143
|
+
}
|
144
|
+
|
145
|
+
/**
|
146
|
+
* For an attribute with multiple interpolation tags,
|
147
|
+
* e.g. attr="some-{{thing | filter}}", in order to combine
|
148
|
+
* the whole thing into a single watchable expression, we
|
149
|
+
* have to inline those filters. This function does exactly
|
150
|
+
* that. This is a bit hacky but it avoids heavy changes
|
151
|
+
* to directive parser and watcher mechanism.
|
152
|
+
*
|
153
|
+
* @param {String} exp
|
154
|
+
* @return {String}
|
155
|
+
*/
|
156
|
+
|
157
|
+
var filterRE = /[^|]\|[^|]/
|
158
|
+
function inlineFilters (exp) {
|
159
|
+
if (!filterRE.test(exp)) {
|
160
|
+
return '(' + exp + ')'
|
161
|
+
} else {
|
162
|
+
var dir = dirParser.parse(exp)[0]
|
163
|
+
if (!dir.filters) {
|
164
|
+
return '(' + exp + ')'
|
165
|
+
} else {
|
166
|
+
exp = dir.expression
|
167
|
+
for (var i = 0, l = dir.filters.length; i < l; i++) {
|
168
|
+
var filter = dir.filters[i]
|
169
|
+
var args = filter.args
|
170
|
+
? ',"' + filter.args.join('","') + '"'
|
171
|
+
: ''
|
172
|
+
exp = 'this.$options.filters["' + filter.name + '"]' +
|
173
|
+
'.apply(this,[' + exp + args + '])'
|
174
|
+
}
|
175
|
+
return exp
|
176
|
+
}
|
177
|
+
}
|
178
|
+
}
|
@@ -0,0 +1,189 @@
|
|
1
|
+
var _ = require('../util')
|
2
|
+
var addClass = _.addClass
|
3
|
+
var removeClass = _.removeClass
|
4
|
+
var transDurationProp = _.transitionProp + 'Duration'
|
5
|
+
var animDurationProp = _.animationProp + 'Duration'
|
6
|
+
|
7
|
+
var queue = []
|
8
|
+
var queued = false
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Push a job into the transition queue, which is to be
|
12
|
+
* executed on next frame.
|
13
|
+
*
|
14
|
+
* @param {Element} el - target element
|
15
|
+
* @param {Number} dir - 1: enter, -1: leave
|
16
|
+
* @param {Function} op - the actual dom operation
|
17
|
+
* @param {String} cls - the className to remove when the
|
18
|
+
* transition is done.
|
19
|
+
* @param {Function} [cb] - user supplied callback.
|
20
|
+
*/
|
21
|
+
|
22
|
+
function push (el, dir, op, cls, cb) {
|
23
|
+
queue.push({
|
24
|
+
el : el,
|
25
|
+
dir : dir,
|
26
|
+
cb : cb,
|
27
|
+
cls : cls,
|
28
|
+
op : op
|
29
|
+
})
|
30
|
+
if (!queued) {
|
31
|
+
queued = true
|
32
|
+
_.nextTick(flush)
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Flush the queue, and do one forced reflow before
|
38
|
+
* triggering transitions.
|
39
|
+
*/
|
40
|
+
|
41
|
+
function flush () {
|
42
|
+
/* jshint unused: false */
|
43
|
+
var f = document.documentElement.offsetHeight
|
44
|
+
queue.forEach(run)
|
45
|
+
queue = []
|
46
|
+
queued = false
|
47
|
+
}
|
48
|
+
|
49
|
+
/**
|
50
|
+
* Run a transition job.
|
51
|
+
*
|
52
|
+
* @param {Object} job
|
53
|
+
*/
|
54
|
+
|
55
|
+
function run (job) {
|
56
|
+
|
57
|
+
var el = job.el
|
58
|
+
var data = el.__v_trans
|
59
|
+
var cls = job.cls
|
60
|
+
var cb = job.cb
|
61
|
+
var op = job.op
|
62
|
+
var transitionType = getTransitionType(el, data, cls)
|
63
|
+
|
64
|
+
if (job.dir > 0) { // ENTER
|
65
|
+
if (transitionType === 1) {
|
66
|
+
// trigger transition by removing enter class
|
67
|
+
removeClass(el, cls)
|
68
|
+
// only need to listen for transitionend if there's
|
69
|
+
// a user callback
|
70
|
+
if (cb) setupTransitionCb(_.transitionEndEvent)
|
71
|
+
} else if (transitionType === 2) {
|
72
|
+
// animations are triggered when class is added
|
73
|
+
// so we just listen for animationend to remove it.
|
74
|
+
setupTransitionCb(_.animationEndEvent, function () {
|
75
|
+
removeClass(el, cls)
|
76
|
+
})
|
77
|
+
} else {
|
78
|
+
// no transition applicable
|
79
|
+
removeClass(el, cls)
|
80
|
+
if (cb) cb()
|
81
|
+
}
|
82
|
+
} else { // LEAVE
|
83
|
+
if (transitionType) {
|
84
|
+
// leave transitions/animations are both triggered
|
85
|
+
// by adding the class, just remove it on end event.
|
86
|
+
var event = transitionType === 1
|
87
|
+
? _.transitionEndEvent
|
88
|
+
: _.animationEndEvent
|
89
|
+
setupTransitionCb(event, function () {
|
90
|
+
op()
|
91
|
+
removeClass(el, cls)
|
92
|
+
})
|
93
|
+
} else {
|
94
|
+
op()
|
95
|
+
removeClass(el, cls)
|
96
|
+
if (cb) cb()
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* Set up a transition end callback, store the callback
|
102
|
+
* on the element's __v_trans data object, so we can
|
103
|
+
* clean it up if another transition is triggered before
|
104
|
+
* the callback is fired.
|
105
|
+
*
|
106
|
+
* @param {String} event
|
107
|
+
* @param {Function} [cleanupFn]
|
108
|
+
*/
|
109
|
+
|
110
|
+
function setupTransitionCb (event, cleanupFn) {
|
111
|
+
data.event = event
|
112
|
+
var onEnd = data.callback = function transitionCb (e) {
|
113
|
+
if (e.target === el) {
|
114
|
+
_.off(el, event, onEnd)
|
115
|
+
data.event = data.callback = null
|
116
|
+
if (cleanupFn) cleanupFn()
|
117
|
+
if (cb) cb()
|
118
|
+
}
|
119
|
+
}
|
120
|
+
_.on(el, event, onEnd)
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
/**
|
125
|
+
* Get an element's transition type based on the
|
126
|
+
* calculated styles
|
127
|
+
*
|
128
|
+
* @param {Element} el
|
129
|
+
* @param {Object} data
|
130
|
+
* @param {String} className
|
131
|
+
* @return {Number}
|
132
|
+
* 1 - transition
|
133
|
+
* 2 - animation
|
134
|
+
*/
|
135
|
+
|
136
|
+
function getTransitionType (el, data, className) {
|
137
|
+
var type = data.cache && data.cache[className]
|
138
|
+
if (type) return type
|
139
|
+
var inlineStyles = el.style
|
140
|
+
var computedStyles = window.getComputedStyle(el)
|
141
|
+
var transDuration =
|
142
|
+
inlineStyles[transDurationProp] ||
|
143
|
+
computedStyles[transDurationProp]
|
144
|
+
if (transDuration && transDuration !== '0s') {
|
145
|
+
type = 1
|
146
|
+
} else {
|
147
|
+
var animDuration =
|
148
|
+
inlineStyles[animDurationProp] ||
|
149
|
+
computedStyles[animDurationProp]
|
150
|
+
if (animDuration && animDuration !== '0s') {
|
151
|
+
type = 2
|
152
|
+
}
|
153
|
+
}
|
154
|
+
if (type) {
|
155
|
+
if (!data.cache) data.cache = {}
|
156
|
+
data.cache[className] = type
|
157
|
+
}
|
158
|
+
return type
|
159
|
+
}
|
160
|
+
|
161
|
+
/**
|
162
|
+
* Apply CSS transition to an element.
|
163
|
+
*
|
164
|
+
* @param {Element} el
|
165
|
+
* @param {Number} direction - 1: enter, -1: leave
|
166
|
+
* @param {Function} op - the actual DOM operation
|
167
|
+
* @param {Object} data - target element's transition data
|
168
|
+
*/
|
169
|
+
|
170
|
+
module.exports = function (el, direction, op, data, cb) {
|
171
|
+
var prefix = data.id || 'v'
|
172
|
+
var enterClass = prefix + '-enter'
|
173
|
+
var leaveClass = prefix + '-leave'
|
174
|
+
// clean up potential previous unfinished transition
|
175
|
+
if (data.callback) {
|
176
|
+
_.off(el, data.event, data.callback)
|
177
|
+
removeClass(el, enterClass)
|
178
|
+
removeClass(el, leaveClass)
|
179
|
+
data.event = data.callback = null
|
180
|
+
}
|
181
|
+
if (direction > 0) { // enter
|
182
|
+
addClass(el, enterClass)
|
183
|
+
op()
|
184
|
+
push(el, direction, null, enterClass, cb)
|
185
|
+
} else { // leave
|
186
|
+
addClass(el, leaveClass)
|
187
|
+
push(el, direction, op, leaveClass, cb)
|
188
|
+
}
|
189
|
+
}
|