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,15 +0,0 @@
1
- (function(){
2
- "use strict";
3
-
4
- $(function(){
5
- var $select = $('#setting-format select');
6
- if($select.length === 0) return;
7
-
8
- var $options = $('#setting-format-options');
9
- console.log($options);
10
- debugger;
11
- $select.on("change", function(ev){
12
- });
13
- });
14
- })();
15
-
@@ -1,103 +0,0 @@
1
- var Batcher = require('./batcher'),
2
- bindingBatcher = new Batcher(),
3
- bindingId = 1
4
-
5
- /**
6
- * Binding class.
7
- *
8
- * each property on the viewmodel has one corresponding Binding object
9
- * which has multiple directive instances on the DOM
10
- * and multiple computed property dependents
11
- */
12
- function Binding (compiler, key, isExp, isFn) {
13
- this.id = bindingId++
14
- this.value = undefined
15
- this.isExp = !!isExp
16
- this.isFn = isFn
17
- this.root = !this.isExp && key.indexOf('.') === -1
18
- this.compiler = compiler
19
- this.key = key
20
- this.dirs = []
21
- this.subs = []
22
- this.deps = []
23
- this.unbound = false
24
- }
25
-
26
- var BindingProto = Binding.prototype
27
-
28
- /**
29
- * Update value and queue instance updates.
30
- */
31
- BindingProto.update = function (value) {
32
- if (!this.isComputed || this.isFn) {
33
- this.value = value
34
- }
35
- if (this.dirs.length || this.subs.length) {
36
- var self = this
37
- bindingBatcher.push({
38
- id: this.id,
39
- execute: function () {
40
- if (!self.unbound) {
41
- self._update()
42
- }
43
- }
44
- })
45
- }
46
- }
47
-
48
- /**
49
- * Actually update the directives.
50
- */
51
- BindingProto._update = function () {
52
- var i = this.dirs.length,
53
- value = this.val()
54
- while (i--) {
55
- this.dirs[i].$update(value)
56
- }
57
- this.pub()
58
- }
59
-
60
- /**
61
- * Return the valuated value regardless
62
- * of whether it is computed or not
63
- */
64
- BindingProto.val = function () {
65
- return this.isComputed && !this.isFn
66
- ? this.value.$get()
67
- : this.value
68
- }
69
-
70
- /**
71
- * Notify computed properties that depend on this binding
72
- * to update themselves
73
- */
74
- BindingProto.pub = function () {
75
- var i = this.subs.length
76
- while (i--) {
77
- this.subs[i].update()
78
- }
79
- }
80
-
81
- /**
82
- * Unbind the binding, remove itself from all of its dependencies
83
- */
84
- BindingProto.unbind = function () {
85
- // Indicate this has been unbound.
86
- // It's possible this binding will be in
87
- // the batcher's flush queue when its owner
88
- // compiler has already been destroyed.
89
- this.unbound = true
90
- var i = this.dirs.length
91
- while (i--) {
92
- this.dirs[i].$unbind()
93
- }
94
- i = this.deps.length
95
- var subs
96
- while (i--) {
97
- subs = this.deps[i].subs
98
- var j = subs.indexOf(this)
99
- if (j > -1) subs.splice(j, 1)
100
- }
101
- }
102
-
103
- module.exports = Binding
@@ -1,1037 +0,0 @@
1
- var Emitter = require('./emitter'),
2
- Observer = require('./observer'),
3
- config = require('./config'),
4
- utils = require('./utils'),
5
- Binding = require('./binding'),
6
- Directive = require('./directive'),
7
- TextParser = require('./text-parser'),
8
- DepsParser = require('./deps-parser'),
9
- ExpParser = require('./exp-parser'),
10
- ViewModel,
11
-
12
- // cache methods
13
- slice = [].slice,
14
- extend = utils.extend,
15
- hasOwn = ({}).hasOwnProperty,
16
- def = Object.defineProperty,
17
-
18
- // hooks to register
19
- hooks = [
20
- 'created', 'ready',
21
- 'beforeDestroy', 'afterDestroy',
22
- 'attached', 'detached'
23
- ],
24
-
25
- // list of priority directives
26
- // that needs to be checked in specific order
27
- priorityDirectives = [
28
- 'if',
29
- 'repeat',
30
- 'view',
31
- 'component'
32
- ]
33
-
34
- /**
35
- * The DOM compiler
36
- * scans a DOM node and compile bindings for a ViewModel
37
- */
38
- function Compiler (vm, options) {
39
-
40
- var compiler = this,
41
- key, i
42
-
43
- // default state
44
- compiler.init = true
45
- compiler.destroyed = false
46
-
47
- // process and extend options
48
- options = compiler.options = options || {}
49
- utils.processOptions(options)
50
-
51
- // copy compiler options
52
- extend(compiler, options.compilerOptions)
53
- // repeat indicates this is a v-repeat instance
54
- compiler.repeat = compiler.repeat || false
55
- // expCache will be shared between v-repeat instances
56
- compiler.expCache = compiler.expCache || {}
57
-
58
- // initialize element
59
- var el = compiler.el = compiler.setupElement(options)
60
- utils.log('\nnew VM instance: ' + el.tagName + '\n')
61
-
62
- // set other compiler properties
63
- compiler.vm = el.vue_vm = vm
64
- compiler.bindings = utils.hash()
65
- compiler.dirs = []
66
- compiler.deferred = []
67
- compiler.computed = []
68
- compiler.children = []
69
- compiler.emitter = new Emitter(vm)
70
-
71
- // VM ---------------------------------------------------------------------
72
-
73
- // set VM properties
74
- vm.$ = {}
75
- vm.$el = el
76
- vm.$options = options
77
- vm.$compiler = compiler
78
- vm.$event = null
79
-
80
- // set parent & root
81
- var parentVM = options.parent
82
- if (parentVM) {
83
- compiler.parent = parentVM.$compiler
84
- parentVM.$compiler.children.push(compiler)
85
- vm.$parent = parentVM
86
- // inherit lazy option
87
- if (!('lazy' in options)) {
88
- options.lazy = compiler.parent.options.lazy
89
- }
90
- }
91
- vm.$root = getRoot(compiler).vm
92
-
93
- // DATA -------------------------------------------------------------------
94
-
95
- // setup observer
96
- // this is necesarry for all hooks and data observation events
97
- compiler.setupObserver()
98
-
99
- // create bindings for computed properties
100
- if (options.methods) {
101
- for (key in options.methods) {
102
- compiler.createBinding(key)
103
- }
104
- }
105
-
106
- // create bindings for methods
107
- if (options.computed) {
108
- for (key in options.computed) {
109
- compiler.createBinding(key)
110
- }
111
- }
112
-
113
- // initialize data
114
- var data = compiler.data = options.data || {},
115
- defaultData = options.defaultData
116
- if (defaultData) {
117
- for (key in defaultData) {
118
- if (!hasOwn.call(data, key)) {
119
- data[key] = defaultData[key]
120
- }
121
- }
122
- }
123
-
124
- // copy paramAttributes
125
- var params = options.paramAttributes
126
- if (params) {
127
- i = params.length
128
- while (i--) {
129
- data[params[i]] = utils.checkNumber(
130
- compiler.eval(
131
- el.getAttribute(params[i])
132
- )
133
- )
134
- }
135
- }
136
-
137
- // copy data properties to vm
138
- // so user can access them in the created hook
139
- extend(vm, data)
140
- vm.$data = data
141
-
142
- // beforeCompile hook
143
- compiler.execHook('created')
144
-
145
- // the user might have swapped the data ...
146
- data = compiler.data = vm.$data
147
-
148
- // user might also set some properties on the vm
149
- // in which case we should copy back to $data
150
- var vmProp
151
- for (key in vm) {
152
- vmProp = vm[key]
153
- if (
154
- key.charAt(0) !== '$' &&
155
- data[key] !== vmProp &&
156
- typeof vmProp !== 'function'
157
- ) {
158
- data[key] = vmProp
159
- }
160
- }
161
-
162
- // now we can observe the data.
163
- // this will convert data properties to getter/setters
164
- // and emit the first batch of set events, which will
165
- // in turn create the corresponding bindings.
166
- compiler.observeData(data)
167
-
168
- // COMPILE ----------------------------------------------------------------
169
-
170
- // before compiling, resolve content insertion points
171
- if (options.template) {
172
- this.resolveContent()
173
- }
174
-
175
- // now parse the DOM and bind directives.
176
- // During this stage, we will also create bindings for
177
- // encountered keypaths that don't have a binding yet.
178
- compiler.compile(el, true)
179
-
180
- // Any directive that creates child VMs are deferred
181
- // so that when they are compiled, all bindings on the
182
- // parent VM have been created.
183
- i = compiler.deferred.length
184
- while (i--) {
185
- compiler.bindDirective(compiler.deferred[i])
186
- }
187
- compiler.deferred = null
188
-
189
- // extract dependencies for computed properties.
190
- // this will evaluated all collected computed bindings
191
- // and collect get events that are emitted.
192
- if (this.computed.length) {
193
- DepsParser.parse(this.computed)
194
- }
195
-
196
- // done!
197
- compiler.init = false
198
-
199
- // post compile / ready hook
200
- compiler.execHook('ready')
201
- }
202
-
203
- var CompilerProto = Compiler.prototype
204
-
205
- /**
206
- * Initialize the VM/Compiler's element.
207
- * Fill it in with the template if necessary.
208
- */
209
- CompilerProto.setupElement = function (options) {
210
- // create the node first
211
- var el = typeof options.el === 'string'
212
- ? document.querySelector(options.el)
213
- : options.el || document.createElement(options.tagName || 'div')
214
-
215
- var template = options.template,
216
- child, replacer, i, attr, attrs
217
-
218
- if (template) {
219
- // collect anything already in there
220
- if (el.hasChildNodes()) {
221
- this.rawContent = document.createElement('div')
222
- /* jshint boss: true */
223
- while (child = el.firstChild) {
224
- this.rawContent.appendChild(child)
225
- }
226
- }
227
- // replace option: use the first node in
228
- // the template directly
229
- if (options.replace && template.firstChild === template.lastChild) {
230
- replacer = template.firstChild.cloneNode(true)
231
- if (el.parentNode) {
232
- el.parentNode.insertBefore(replacer, el)
233
- el.parentNode.removeChild(el)
234
- }
235
- // copy over attributes
236
- if (el.hasAttributes()) {
237
- i = el.attributes.length
238
- while (i--) {
239
- attr = el.attributes[i]
240
- replacer.setAttribute(attr.name, attr.value)
241
- }
242
- }
243
- // replace
244
- el = replacer
245
- } else {
246
- el.appendChild(template.cloneNode(true))
247
- }
248
-
249
- }
250
-
251
- // apply element options
252
- if (options.id) el.id = options.id
253
- if (options.className) el.className = options.className
254
- attrs = options.attributes
255
- if (attrs) {
256
- for (attr in attrs) {
257
- el.setAttribute(attr, attrs[attr])
258
- }
259
- }
260
-
261
- return el
262
- }
263
-
264
- /**
265
- * Deal with <content> insertion points
266
- * per the Web Components spec
267
- */
268
- CompilerProto.resolveContent = function () {
269
-
270
- var outlets = slice.call(this.el.getElementsByTagName('content')),
271
- raw = this.rawContent,
272
- outlet, select, i, j, main
273
-
274
- i = outlets.length
275
- if (i) {
276
- // first pass, collect corresponding content
277
- // for each outlet.
278
- while (i--) {
279
- outlet = outlets[i]
280
- if (raw) {
281
- select = outlet.getAttribute('select')
282
- if (select) { // select content
283
- outlet.content =
284
- slice.call(raw.querySelectorAll(select))
285
- } else { // default content
286
- main = outlet
287
- }
288
- } else { // fallback content
289
- outlet.content =
290
- slice.call(outlet.childNodes)
291
- }
292
- }
293
- // second pass, actually insert the contents
294
- for (i = 0, j = outlets.length; i < j; i++) {
295
- outlet = outlets[i]
296
- if (outlet === main) continue
297
- insert(outlet, outlet.content)
298
- }
299
- // finally insert the main content
300
- if (raw && main) {
301
- insert(main, slice.call(raw.childNodes))
302
- }
303
- }
304
-
305
- function insert (outlet, contents) {
306
- var parent = outlet.parentNode,
307
- i = 0, j = contents.length
308
- for (; i < j; i++) {
309
- parent.insertBefore(contents[i], outlet)
310
- }
311
- parent.removeChild(outlet)
312
- }
313
-
314
- this.rawContent = null
315
- }
316
-
317
- /**
318
- * Setup observer.
319
- * The observer listens for get/set/mutate events on all VM
320
- * values/objects and trigger corresponding binding updates.
321
- * It also listens for lifecycle hooks.
322
- */
323
- CompilerProto.setupObserver = function () {
324
-
325
- var compiler = this,
326
- bindings = compiler.bindings,
327
- options = compiler.options,
328
- observer = compiler.observer = new Emitter(compiler.vm)
329
-
330
- // a hash to hold event proxies for each root level key
331
- // so they can be referenced and removed later
332
- observer.proxies = {}
333
-
334
- // add own listeners which trigger binding updates
335
- observer
336
- .on('get', onGet)
337
- .on('set', onSet)
338
- .on('mutate', onSet)
339
-
340
- // register hooks
341
- var i = hooks.length, j, hook, fns
342
- while (i--) {
343
- hook = hooks[i]
344
- fns = options[hook]
345
- if (Array.isArray(fns)) {
346
- j = fns.length
347
- // since hooks were merged with child at head,
348
- // we loop reversely.
349
- while (j--) {
350
- registerHook(hook, fns[j])
351
- }
352
- } else if (fns) {
353
- registerHook(hook, fns)
354
- }
355
- }
356
-
357
- // broadcast attached/detached hooks
358
- observer
359
- .on('hook:attached', function () {
360
- broadcast(1)
361
- })
362
- .on('hook:detached', function () {
363
- broadcast(0)
364
- })
365
-
366
- function onGet (key) {
367
- check(key)
368
- DepsParser.catcher.emit('get', bindings[key])
369
- }
370
-
371
- function onSet (key, val, mutation) {
372
- observer.emit('change:' + key, val, mutation)
373
- check(key)
374
- bindings[key].update(val)
375
- }
376
-
377
- function registerHook (hook, fn) {
378
- observer.on('hook:' + hook, function () {
379
- fn.call(compiler.vm)
380
- })
381
- }
382
-
383
- function broadcast (event) {
384
- var children = compiler.children
385
- if (children) {
386
- var child, i = children.length
387
- while (i--) {
388
- child = children[i]
389
- if (child.el.parentNode) {
390
- event = 'hook:' + (event ? 'attached' : 'detached')
391
- child.observer.emit(event)
392
- child.emitter.emit(event)
393
- }
394
- }
395
- }
396
- }
397
-
398
- function check (key) {
399
- if (!bindings[key]) {
400
- compiler.createBinding(key)
401
- }
402
- }
403
- }
404
-
405
- CompilerProto.observeData = function (data) {
406
-
407
- var compiler = this,
408
- observer = compiler.observer
409
-
410
- // recursively observe nested properties
411
- Observer.observe(data, '', observer)
412
-
413
- // also create binding for top level $data
414
- // so it can be used in templates too
415
- var $dataBinding = compiler.bindings['$data'] = new Binding(compiler, '$data')
416
- $dataBinding.update(data)
417
-
418
- // allow $data to be swapped
419
- def(compiler.vm, '$data', {
420
- get: function () {
421
- compiler.observer.emit('get', '$data')
422
- return compiler.data
423
- },
424
- set: function (newData) {
425
- var oldData = compiler.data
426
- Observer.unobserve(oldData, '', observer)
427
- compiler.data = newData
428
- Observer.copyPaths(newData, oldData)
429
- Observer.observe(newData, '', observer)
430
- update()
431
- }
432
- })
433
-
434
- // emit $data change on all changes
435
- observer
436
- .on('set', onSet)
437
- .on('mutate', onSet)
438
-
439
- function onSet (key) {
440
- if (key !== '$data') update()
441
- }
442
-
443
- function update () {
444
- $dataBinding.update(compiler.data)
445
- observer.emit('change:$data', compiler.data)
446
- }
447
- }
448
-
449
- /**
450
- * Compile a DOM node (recursive)
451
- */
452
- CompilerProto.compile = function (node, root) {
453
- var nodeType = node.nodeType
454
- if (nodeType === 1 && node.tagName !== 'SCRIPT') { // a normal node
455
- this.compileElement(node, root)
456
- } else if (nodeType === 3 && config.interpolate) {
457
- this.compileTextNode(node)
458
- }
459
- }
460
-
461
- /**
462
- * Check for a priority directive
463
- * If it is present and valid, return true to skip the rest
464
- */
465
- CompilerProto.checkPriorityDir = function (dirname, node, root) {
466
- var expression, directive, Ctor
467
- if (
468
- dirname === 'component' &&
469
- root !== true &&
470
- (Ctor = this.resolveComponent(node, undefined, true))
471
- ) {
472
- directive = this.parseDirective(dirname, '', node)
473
- directive.Ctor = Ctor
474
- } else {
475
- expression = utils.attr(node, dirname)
476
- directive = expression && this.parseDirective(dirname, expression, node)
477
- }
478
- if (directive) {
479
- if (root === true) {
480
- utils.warn(
481
- 'Directive v-' + dirname + ' cannot be used on an already instantiated ' +
482
- 'VM\'s root node. Use it from the parent\'s template instead.'
483
- )
484
- return
485
- }
486
- this.deferred.push(directive)
487
- return true
488
- }
489
- }
490
-
491
- /**
492
- * Compile normal directives on a node
493
- */
494
- CompilerProto.compileElement = function (node, root) {
495
-
496
- // textarea is pretty annoying
497
- // because its value creates childNodes which
498
- // we don't want to compile.
499
- if (node.tagName === 'TEXTAREA' && node.value) {
500
- node.value = this.eval(node.value)
501
- }
502
-
503
- // only compile if this element has attributes
504
- // or its tagName contains a hyphen (which means it could
505
- // potentially be a custom element)
506
- if (node.hasAttributes() || node.tagName.indexOf('-') > -1) {
507
-
508
- // skip anything with v-pre
509
- if (utils.attr(node, 'pre') !== null) {
510
- return
511
- }
512
-
513
- var i, l, j, k
514
-
515
- // check priority directives.
516
- // if any of them are present, it will take over the node with a childVM
517
- // so we can skip the rest
518
- for (i = 0, l = priorityDirectives.length; i < l; i++) {
519
- if (this.checkPriorityDir(priorityDirectives[i], node, root)) {
520
- return
521
- }
522
- }
523
-
524
- // check transition & animation properties
525
- node.vue_trans = utils.attr(node, 'transition')
526
- node.vue_anim = utils.attr(node, 'animation')
527
- node.vue_effect = this.eval(utils.attr(node, 'effect'))
528
-
529
- var prefix = config.prefix + '-',
530
- params = this.options.paramAttributes,
531
- attr, attrname, isDirective, exp, directives, directive, dirname
532
-
533
- // v-with has special priority among the rest
534
- // it needs to pull in the value from the parent before
535
- // computed properties are evaluated, because at this stage
536
- // the computed properties have not set up their dependencies yet.
537
- if (root) {
538
- var withExp = utils.attr(node, 'with')
539
- if (withExp) {
540
- directives = this.parseDirective('with', withExp, node, true)
541
- for (j = 0, k = directives.length; j < k; j++) {
542
- this.bindDirective(directives[j], this.parent)
543
- }
544
- }
545
- }
546
-
547
- var attrs = slice.call(node.attributes)
548
- for (i = 0, l = attrs.length; i < l; i++) {
549
-
550
- attr = attrs[i]
551
- attrname = attr.name
552
- isDirective = false
553
-
554
- if (attrname.indexOf(prefix) === 0) {
555
- // a directive - split, parse and bind it.
556
- isDirective = true
557
- dirname = attrname.slice(prefix.length)
558
- // build with multiple: true
559
- directives = this.parseDirective(dirname, attr.value, node, true)
560
- // loop through clauses (separated by ",")
561
- // inside each attribute
562
- for (j = 0, k = directives.length; j < k; j++) {
563
- this.bindDirective(directives[j])
564
- }
565
- } else if (config.interpolate) {
566
- // non directive attribute, check interpolation tags
567
- exp = TextParser.parseAttr(attr.value)
568
- if (exp) {
569
- directive = this.parseDirective('attr', exp, node)
570
- directive.arg = attrname
571
- if (params && params.indexOf(attrname) > -1) {
572
- // a param attribute... we should use the parent binding
573
- // to avoid circular updates like size={{size}}
574
- this.bindDirective(directive, this.parent)
575
- } else {
576
- this.bindDirective(directive)
577
- }
578
- }
579
- }
580
-
581
- if (isDirective && dirname !== 'cloak') {
582
- node.removeAttribute(attrname)
583
- }
584
- }
585
-
586
- }
587
-
588
- // recursively compile childNodes
589
- if (node.hasChildNodes()) {
590
- slice.call(node.childNodes).forEach(this.compile, this)
591
- }
592
- }
593
-
594
- /**
595
- * Compile a text node
596
- */
597
- CompilerProto.compileTextNode = function (node) {
598
-
599
- var tokens = TextParser.parse(node.nodeValue)
600
- if (!tokens) return
601
- var el, token, directive
602
-
603
- for (var i = 0, l = tokens.length; i < l; i++) {
604
-
605
- token = tokens[i]
606
- directive = null
607
-
608
- if (token.key) { // a binding
609
- if (token.key.charAt(0) === '>') { // a partial
610
- el = document.createComment('ref')
611
- directive = this.parseDirective('partial', token.key.slice(1), el)
612
- } else {
613
- if (!token.html) { // text binding
614
- el = document.createTextNode('')
615
- directive = this.parseDirective('text', token.key, el)
616
- } else { // html binding
617
- el = document.createComment(config.prefix + '-html')
618
- directive = this.parseDirective('html', token.key, el)
619
- }
620
- }
621
- } else { // a plain string
622
- el = document.createTextNode(token)
623
- }
624
-
625
- // insert node
626
- node.parentNode.insertBefore(el, node)
627
- // bind directive
628
- this.bindDirective(directive)
629
-
630
- }
631
- node.parentNode.removeChild(node)
632
- }
633
-
634
- /**
635
- * Parse a directive name/value pair into one or more
636
- * directive instances
637
- */
638
- CompilerProto.parseDirective = function (name, value, el, multiple) {
639
- var compiler = this,
640
- definition = compiler.getOption('directives', name)
641
- if (definition) {
642
- // parse into AST-like objects
643
- var asts = Directive.parse(value)
644
- return multiple
645
- ? asts.map(build)
646
- : build(asts[0])
647
- }
648
- function build (ast) {
649
- return new Directive(name, ast, definition, compiler, el)
650
- }
651
- }
652
-
653
- /**
654
- * Add a directive instance to the correct binding & viewmodel
655
- */
656
- CompilerProto.bindDirective = function (directive, bindingOwner) {
657
-
658
- if (!directive) return
659
-
660
- // keep track of it so we can unbind() later
661
- this.dirs.push(directive)
662
-
663
- // for empty or literal directives, simply call its bind()
664
- // and we're done.
665
- if (directive.isEmpty || directive.isLiteral) {
666
- if (directive.bind) directive.bind()
667
- return
668
- }
669
-
670
- // otherwise, we got more work to do...
671
- var binding,
672
- compiler = bindingOwner || this,
673
- key = directive.key
674
-
675
- if (directive.isExp) {
676
- // expression bindings are always created on current compiler
677
- binding = compiler.createBinding(key, directive)
678
- } else {
679
- // recursively locate which compiler owns the binding
680
- while (compiler) {
681
- if (compiler.hasKey(key)) {
682
- break
683
- } else {
684
- compiler = compiler.parent
685
- }
686
- }
687
- compiler = compiler || this
688
- binding = compiler.bindings[key] || compiler.createBinding(key)
689
- }
690
- binding.dirs.push(directive)
691
- directive.binding = binding
692
-
693
- var value = binding.val()
694
- // invoke bind hook if exists
695
- if (directive.bind) {
696
- directive.bind(value)
697
- }
698
- // set initial value
699
- directive.$update(value, true)
700
- }
701
-
702
- /**
703
- * Create binding and attach getter/setter for a key to the viewmodel object
704
- */
705
- CompilerProto.createBinding = function (key, directive) {
706
-
707
- utils.log(' created binding: ' + key)
708
-
709
- var compiler = this,
710
- methods = compiler.options.methods,
711
- isExp = directive && directive.isExp,
712
- isFn = (directive && directive.isFn) || (methods && methods[key]),
713
- bindings = compiler.bindings,
714
- computed = compiler.options.computed,
715
- binding = new Binding(compiler, key, isExp, isFn)
716
-
717
- if (isExp) {
718
- // expression bindings are anonymous
719
- compiler.defineExp(key, binding, directive)
720
- } else if (isFn) {
721
- bindings[key] = binding
722
- compiler.defineVmProp(key, binding, methods[key])
723
- } else {
724
- bindings[key] = binding
725
- if (binding.root) {
726
- // this is a root level binding. we need to define getter/setters for it.
727
- if (computed && computed[key]) {
728
- // computed property
729
- compiler.defineComputed(key, binding, computed[key])
730
- } else if (key.charAt(0) !== '$') {
731
- // normal property
732
- compiler.defineDataProp(key, binding)
733
- } else {
734
- // properties that start with $ are meta properties
735
- // they should be kept on the vm but not in the data object.
736
- compiler.defineVmProp(key, binding, compiler.data[key])
737
- delete compiler.data[key]
738
- }
739
- } else if (computed && computed[utils.baseKey(key)]) {
740
- // nested path on computed property
741
- compiler.defineExp(key, binding)
742
- } else {
743
- // ensure path in data so that computed properties that
744
- // access the path don't throw an error and can collect
745
- // dependencies
746
- Observer.ensurePath(compiler.data, key)
747
- var parentKey = key.slice(0, key.lastIndexOf('.'))
748
- if (!bindings[parentKey]) {
749
- // this is a nested value binding, but the binding for its parent
750
- // has not been created yet. We better create that one too.
751
- compiler.createBinding(parentKey)
752
- }
753
- }
754
- }
755
- return binding
756
- }
757
-
758
- /**
759
- * Define the getter/setter to proxy a root-level
760
- * data property on the VM
761
- */
762
- CompilerProto.defineDataProp = function (key, binding) {
763
- var compiler = this,
764
- data = compiler.data,
765
- ob = data.__emitter__
766
-
767
- // make sure the key is present in data
768
- // so it can be observed
769
- if (!(hasOwn.call(data, key))) {
770
- data[key] = undefined
771
- }
772
-
773
- // if the data object is already observed, but the key
774
- // is not observed, we need to add it to the observed keys.
775
- if (ob && !(hasOwn.call(ob.values, key))) {
776
- Observer.convertKey(data, key)
777
- }
778
-
779
- binding.value = data[key]
780
-
781
- def(compiler.vm, key, {
782
- get: function () {
783
- return compiler.data[key]
784
- },
785
- set: function (val) {
786
- compiler.data[key] = val
787
- }
788
- })
789
- }
790
-
791
- /**
792
- * Define a vm property, e.g. $index, $key, or mixin methods
793
- * which are bindable but only accessible on the VM,
794
- * not in the data.
795
- */
796
- CompilerProto.defineVmProp = function (key, binding, value) {
797
- var ob = this.observer
798
- binding.value = value
799
- def(this.vm, key, {
800
- get: function () {
801
- if (Observer.shouldGet) ob.emit('get', key)
802
- return binding.value
803
- },
804
- set: function (val) {
805
- ob.emit('set', key, val)
806
- }
807
- })
808
- }
809
-
810
- /**
811
- * Define an expression binding, which is essentially
812
- * an anonymous computed property
813
- */
814
- CompilerProto.defineExp = function (key, binding, directive) {
815
- var computedKey = directive && directive.computedKey,
816
- exp = computedKey ? directive.expression : key,
817
- getter = this.expCache[exp]
818
- if (!getter) {
819
- getter = this.expCache[exp] = ExpParser.parse(computedKey || key, this)
820
- }
821
- if (getter) {
822
- this.markComputed(binding, getter)
823
- }
824
- }
825
-
826
- /**
827
- * Define a computed property on the VM
828
- */
829
- CompilerProto.defineComputed = function (key, binding, value) {
830
- this.markComputed(binding, value)
831
- def(this.vm, key, {
832
- get: binding.value.$get,
833
- set: binding.value.$set
834
- })
835
- }
836
-
837
- /**
838
- * Process a computed property binding
839
- * so its getter/setter are bound to proper context
840
- */
841
- CompilerProto.markComputed = function (binding, value) {
842
- binding.isComputed = true
843
- // bind the accessors to the vm
844
- if (binding.isFn) {
845
- binding.value = value
846
- } else {
847
- if (typeof value === 'function') {
848
- value = { $get: value }
849
- }
850
- binding.value = {
851
- $get: utils.bind(value.$get, this.vm),
852
- $set: value.$set
853
- ? utils.bind(value.$set, this.vm)
854
- : undefined
855
- }
856
- }
857
- // keep track for dep parsing later
858
- this.computed.push(binding)
859
- }
860
-
861
- /**
862
- * Retrive an option from the compiler
863
- */
864
- CompilerProto.getOption = function (type, id, silent) {
865
- var opts = this.options,
866
- parent = this.parent,
867
- globalAssets = config.globalAssets,
868
- res = (opts[type] && opts[type][id]) || (
869
- parent
870
- ? parent.getOption(type, id, silent)
871
- : globalAssets[type] && globalAssets[type][id]
872
- )
873
- if (!res && !silent && typeof id === 'string') {
874
- utils.warn('Unknown ' + type.slice(0, -1) + ': ' + id)
875
- }
876
- return res
877
- }
878
-
879
- /**
880
- * Emit lifecycle events to trigger hooks
881
- */
882
- CompilerProto.execHook = function (event) {
883
- event = 'hook:' + event
884
- this.observer.emit(event)
885
- this.emitter.emit(event)
886
- }
887
-
888
- /**
889
- * Check if a compiler's data contains a keypath
890
- */
891
- CompilerProto.hasKey = function (key) {
892
- var baseKey = utils.baseKey(key)
893
- return hasOwn.call(this.data, baseKey) ||
894
- hasOwn.call(this.vm, baseKey)
895
- }
896
-
897
- /**
898
- * Do a one-time eval of a string that potentially
899
- * includes bindings. It accepts additional raw data
900
- * because we need to dynamically resolve v-component
901
- * before a childVM is even compiled...
902
- */
903
- CompilerProto.eval = function (exp, data) {
904
- var parsed = TextParser.parseAttr(exp)
905
- return parsed
906
- ? ExpParser.eval(parsed, this, data)
907
- : exp
908
- }
909
-
910
- /**
911
- * Resolve a Component constructor for an element
912
- * with the data to be used
913
- */
914
- CompilerProto.resolveComponent = function (node, data, test) {
915
-
916
- // late require to avoid circular deps
917
- ViewModel = ViewModel || require('./viewmodel')
918
-
919
- var exp = utils.attr(node, 'component'),
920
- tagName = node.tagName,
921
- id = this.eval(exp, data),
922
- tagId = (tagName.indexOf('-') > 0 && tagName.toLowerCase()),
923
- Ctor = this.getOption('components', id || tagId, true)
924
-
925
- if (id && !Ctor) {
926
- utils.warn('Unknown component: ' + id)
927
- }
928
-
929
- return test
930
- ? exp === ''
931
- ? ViewModel
932
- : Ctor
933
- : Ctor || ViewModel
934
- }
935
-
936
- /**
937
- * Unbind and remove element
938
- */
939
- CompilerProto.destroy = function (noRemove) {
940
-
941
- // avoid being called more than once
942
- // this is irreversible!
943
- if (this.destroyed) return
944
-
945
- var compiler = this,
946
- i, j, key, dir, dirs, binding,
947
- vm = compiler.vm,
948
- el = compiler.el,
949
- directives = compiler.dirs,
950
- computed = compiler.computed,
951
- bindings = compiler.bindings,
952
- children = compiler.children,
953
- parent = compiler.parent
954
-
955
- compiler.execHook('beforeDestroy')
956
-
957
- // unobserve data
958
- Observer.unobserve(compiler.data, '', compiler.observer)
959
-
960
- // destroy all children
961
- // do not remove their elements since the parent
962
- // may have transitions and the children may not
963
- i = children.length
964
- while (i--) {
965
- children[i].destroy(true)
966
- }
967
-
968
- // unbind all direcitves
969
- i = directives.length
970
- while (i--) {
971
- dir = directives[i]
972
- // if this directive is an instance of an external binding
973
- // e.g. a directive that refers to a variable on the parent VM
974
- // we need to remove it from that binding's directives
975
- // * empty and literal bindings do not have binding.
976
- if (dir.binding && dir.binding.compiler !== compiler) {
977
- dirs = dir.binding.dirs
978
- if (dirs) {
979
- j = dirs.indexOf(dir)
980
- if (j > -1) dirs.splice(j, 1)
981
- }
982
- }
983
- dir.$unbind()
984
- }
985
-
986
- // unbind all computed, anonymous bindings
987
- i = computed.length
988
- while (i--) {
989
- computed[i].unbind()
990
- }
991
-
992
- // unbind all keypath bindings
993
- for (key in bindings) {
994
- binding = bindings[key]
995
- if (binding) {
996
- binding.unbind()
997
- }
998
- }
999
-
1000
- // remove self from parent
1001
- if (parent) {
1002
- j = parent.children.indexOf(compiler)
1003
- if (j > -1) parent.children.splice(j, 1)
1004
- }
1005
-
1006
- // finally remove dom element
1007
- if (!noRemove) {
1008
- if (el === document.body) {
1009
- el.innerHTML = ''
1010
- } else {
1011
- vm.$remove()
1012
- }
1013
- }
1014
- el.vue_vm = null
1015
-
1016
- compiler.destroyed = true
1017
- // emit destroy hook
1018
- compiler.execHook('afterDestroy')
1019
-
1020
- // finally, unregister all listeners
1021
- compiler.observer.off()
1022
- compiler.emitter.off()
1023
- }
1024
-
1025
- // Helpers --------------------------------------------------------------------
1026
-
1027
- /**
1028
- * shorthand for getting root compiler
1029
- */
1030
- function getRoot (compiler) {
1031
- while (compiler.parent) {
1032
- compiler = compiler.parent
1033
- }
1034
- return compiler
1035
- }
1036
-
1037
- module.exports = Compiler