mirror of
https://github.com/fluent/fluentd-ui.git
synced 2025-08-10 00:07:08 +02:00
Change to use vendor/assets/*/bower/* for js
This commit is contained in:
parent
3c37a6201b
commit
8eaa1a12fc
@ -15,6 +15,6 @@
|
||||
//= require sb-admin-v2/bootstrap
|
||||
//= require sb-admin-v2/plugins/dataTables/jquery.dataTables
|
||||
//= require sb-admin-v2/plugins/dataTables/dataTables.bootstrap
|
||||
//= require vue-0.10.4
|
||||
//= require promise-1.0.0
|
||||
//= require bower/vue/dist/vue
|
||||
//= require bower/es6-promise/promise
|
||||
//= require_tree .
|
||||
|
15
vendor/assets/javascripts/bower/es6-promise/.bower.json
vendored
Normal file
15
vendor/assets/javascripts/bower/es6-promise/.bower.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "es6-promise",
|
||||
"version": "1.0.0",
|
||||
"main": "./promise.js",
|
||||
"homepage": "https://github.com/components/es6-promise",
|
||||
"_release": "1.0.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.0.0",
|
||||
"commit": "c95149ffaa2e8162601c57d4282362eac84f929b"
|
||||
},
|
||||
"_source": "git://github.com/components/es6-promise.git",
|
||||
"_target": "~1.0.0",
|
||||
"_originalSource": "es6-promise"
|
||||
}
|
5
vendor/assets/javascripts/bower/es6-promise/bower.json
vendored
Normal file
5
vendor/assets/javascripts/bower/es6-promise/bower.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "es6-promise",
|
||||
"version": "1.0.0",
|
||||
"main": "./promise.js"
|
||||
}
|
1
vendor/assets/javascripts/bower/es6-promise/promise.min.js
vendored
Normal file
1
vendor/assets/javascripts/bower/es6-promise/promise.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
29
vendor/assets/javascripts/bower/vue/.bower.json
vendored
Normal file
29
vendor/assets/javascripts/bower/vue/.bower.json
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "vue",
|
||||
"version": "0.10.4",
|
||||
"main": "dist/vue.js",
|
||||
"description": "Simple, Fast & Composable MVVM for building interative interfaces",
|
||||
"authors": [
|
||||
"Evan You <yyx990803@gmail.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
".*",
|
||||
"examples",
|
||||
"test",
|
||||
"tasks",
|
||||
"Gruntfile.js",
|
||||
"*.json",
|
||||
"*.md"
|
||||
],
|
||||
"homepage": "https://github.com/yyx990803/vue",
|
||||
"_release": "0.10.4",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.10.4",
|
||||
"commit": "d3758fc7e17a0e115092c5fc89264ec7fff7ea39"
|
||||
},
|
||||
"_source": "git://github.com/yyx990803/vue.git",
|
||||
"_target": "~0.10.0",
|
||||
"_originalSource": "vue"
|
||||
}
|
21
vendor/assets/javascripts/bower/vue/LICENSE
vendored
Normal file
21
vendor/assets/javascripts/bower/vue/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Yuxi Evan You
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
7
vendor/assets/javascripts/bower/vue/dist/vue.min.js
vendored
Normal file
7
vendor/assets/javascripts/bower/vue/dist/vue.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
45
vendor/assets/javascripts/bower/vue/src/batcher.js
vendored
Normal file
45
vendor/assets/javascripts/bower/vue/src/batcher.js
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
var utils = require('./utils')
|
||||
|
||||
function Batcher () {
|
||||
this.reset()
|
||||
}
|
||||
|
||||
var BatcherProto = Batcher.prototype
|
||||
|
||||
BatcherProto.push = function (job) {
|
||||
if (!job.id || !this.has[job.id]) {
|
||||
this.queue.push(job)
|
||||
this.has[job.id] = job
|
||||
if (!this.waiting) {
|
||||
this.waiting = true
|
||||
utils.nextTick(utils.bind(this.flush, this))
|
||||
}
|
||||
} else if (job.override) {
|
||||
var oldJob = this.has[job.id]
|
||||
oldJob.cancelled = true
|
||||
this.queue.push(job)
|
||||
this.has[job.id] = job
|
||||
}
|
||||
}
|
||||
|
||||
BatcherProto.flush = function () {
|
||||
// before flush hook
|
||||
if (this._preFlush) this._preFlush()
|
||||
// do not cache length because more jobs might be pushed
|
||||
// as we execute existing jobs
|
||||
for (var i = 0; i < this.queue.length; i++) {
|
||||
var job = this.queue[i]
|
||||
if (!job.cancelled) {
|
||||
job.execute()
|
||||
}
|
||||
}
|
||||
this.reset()
|
||||
}
|
||||
|
||||
BatcherProto.reset = function () {
|
||||
this.has = utils.hash()
|
||||
this.queue = []
|
||||
this.waiting = false
|
||||
}
|
||||
|
||||
module.exports = Batcher
|
103
vendor/assets/javascripts/bower/vue/src/binding.js
vendored
Normal file
103
vendor/assets/javascripts/bower/vue/src/binding.js
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
var Batcher = require('./batcher'),
|
||||
bindingBatcher = new Batcher(),
|
||||
bindingId = 1
|
||||
|
||||
/**
|
||||
* Binding class.
|
||||
*
|
||||
* each property on the viewmodel has one corresponding Binding object
|
||||
* which has multiple directive instances on the DOM
|
||||
* and multiple computed property dependents
|
||||
*/
|
||||
function Binding (compiler, key, isExp, isFn) {
|
||||
this.id = bindingId++
|
||||
this.value = undefined
|
||||
this.isExp = !!isExp
|
||||
this.isFn = isFn
|
||||
this.root = !this.isExp && key.indexOf('.') === -1
|
||||
this.compiler = compiler
|
||||
this.key = key
|
||||
this.dirs = []
|
||||
this.subs = []
|
||||
this.deps = []
|
||||
this.unbound = false
|
||||
}
|
||||
|
||||
var BindingProto = Binding.prototype
|
||||
|
||||
/**
|
||||
* Update value and queue instance updates.
|
||||
*/
|
||||
BindingProto.update = function (value) {
|
||||
if (!this.isComputed || this.isFn) {
|
||||
this.value = value
|
||||
}
|
||||
if (this.dirs.length || this.subs.length) {
|
||||
var self = this
|
||||
bindingBatcher.push({
|
||||
id: this.id,
|
||||
execute: function () {
|
||||
if (!self.unbound) {
|
||||
self._update()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually update the directives.
|
||||
*/
|
||||
BindingProto._update = function () {
|
||||
var i = this.dirs.length,
|
||||
value = this.val()
|
||||
while (i--) {
|
||||
this.dirs[i].$update(value)
|
||||
}
|
||||
this.pub()
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the valuated value regardless
|
||||
* of whether it is computed or not
|
||||
*/
|
||||
BindingProto.val = function () {
|
||||
return this.isComputed && !this.isFn
|
||||
? this.value.$get()
|
||||
: this.value
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify computed properties that depend on this binding
|
||||
* to update themselves
|
||||
*/
|
||||
BindingProto.pub = function () {
|
||||
var i = this.subs.length
|
||||
while (i--) {
|
||||
this.subs[i].update()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbind the binding, remove itself from all of its dependencies
|
||||
*/
|
||||
BindingProto.unbind = function () {
|
||||
// Indicate this has been unbound.
|
||||
// It's possible this binding will be in
|
||||
// the batcher's flush queue when its owner
|
||||
// compiler has already been destroyed.
|
||||
this.unbound = true
|
||||
var i = this.dirs.length
|
||||
while (i--) {
|
||||
this.dirs[i].$unbind()
|
||||
}
|
||||
i = this.deps.length
|
||||
var subs
|
||||
while (i--) {
|
||||
subs = this.deps[i].subs
|
||||
var j = subs.indexOf(this)
|
||||
if (j > -1) subs.splice(j, 1)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Binding
|
1016
vendor/assets/javascripts/bower/vue/src/compiler.js
vendored
Normal file
1016
vendor/assets/javascripts/bower/vue/src/compiler.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
19
vendor/assets/javascripts/bower/vue/src/config.js
vendored
Normal file
19
vendor/assets/javascripts/bower/vue/src/config.js
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
var TextParser = require('./text-parser')
|
||||
|
||||
module.exports = {
|
||||
prefix : 'v',
|
||||
debug : false,
|
||||
silent : false,
|
||||
enterClass : 'v-enter',
|
||||
leaveClass : 'v-leave',
|
||||
interpolate : true
|
||||
}
|
||||
|
||||
Object.defineProperty(module.exports, 'delimiters', {
|
||||
get: function () {
|
||||
return TextParser.delimiters
|
||||
},
|
||||
set: function (delimiters) {
|
||||
TextParser.setDelimiters(delimiters)
|
||||
}
|
||||
})
|
65
vendor/assets/javascripts/bower/vue/src/deps-parser.js
vendored
Normal file
65
vendor/assets/javascripts/bower/vue/src/deps-parser.js
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
var Emitter = require('./emitter'),
|
||||
utils = require('./utils'),
|
||||
Observer = require('./observer'),
|
||||
catcher = new Emitter()
|
||||
|
||||
/**
|
||||
* Auto-extract the dependencies of a computed property
|
||||
* by recording the getters triggered when evaluating it.
|
||||
*/
|
||||
function catchDeps (binding) {
|
||||
if (binding.isFn) return
|
||||
utils.log('\n- ' + binding.key)
|
||||
var got = utils.hash()
|
||||
binding.deps = []
|
||||
catcher.on('get', function (dep) {
|
||||
var has = got[dep.key]
|
||||
if (
|
||||
// avoid duplicate bindings
|
||||
(has && has.compiler === dep.compiler) ||
|
||||
// avoid repeated items as dependency
|
||||
// only when the binding is from self or the parent chain
|
||||
(dep.compiler.repeat && !isParentOf(dep.compiler, binding.compiler))
|
||||
) {
|
||||
return
|
||||
}
|
||||
got[dep.key] = dep
|
||||
utils.log(' - ' + dep.key)
|
||||
binding.deps.push(dep)
|
||||
dep.subs.push(binding)
|
||||
})
|
||||
binding.value.$get()
|
||||
catcher.off('get')
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if A is a parent of or equals B
|
||||
*/
|
||||
function isParentOf (a, b) {
|
||||
while (b) {
|
||||
if (a === b) {
|
||||
return true
|
||||
}
|
||||
b = b.parent
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
/**
|
||||
* the observer that catches events triggered by getters
|
||||
*/
|
||||
catcher: catcher,
|
||||
|
||||
/**
|
||||
* parse a list of computed property bindings
|
||||
*/
|
||||
parse: function (bindings) {
|
||||
utils.log('\nparsing dependencies...')
|
||||
Observer.shouldGet = true
|
||||
bindings.forEach(catchDeps)
|
||||
Observer.shouldGet = false
|
||||
utils.log('\ndone.')
|
||||
}
|
||||
|
||||
}
|
256
vendor/assets/javascripts/bower/vue/src/directive.js
vendored
Normal file
256
vendor/assets/javascripts/bower/vue/src/directive.js
vendored
Normal file
@ -0,0 +1,256 @@
|
||||
var dirId = 1,
|
||||
ARG_RE = /^[\w\$-]+$/,
|
||||
FILTER_TOKEN_RE = /[^\s'"]+|'[^']+'|"[^"]+"/g,
|
||||
NESTING_RE = /^\$(parent|root)\./,
|
||||
SINGLE_VAR_RE = /^[\w\.$]+$/,
|
||||
QUOTE_RE = /"/g
|
||||
|
||||
/**
|
||||
* Directive class
|
||||
* represents a single directive instance in the DOM
|
||||
*/
|
||||
function Directive (name, ast, definition, compiler, el) {
|
||||
|
||||
this.id = dirId++
|
||||
this.name = name
|
||||
this.compiler = compiler
|
||||
this.vm = compiler.vm
|
||||
this.el = el
|
||||
this.computeFilters = false
|
||||
this.key = ast.key
|
||||
this.arg = ast.arg
|
||||
this.expression = ast.expression
|
||||
|
||||
var isEmpty = this.expression === ''
|
||||
|
||||
// mix in properties from the directive definition
|
||||
if (typeof definition === 'function') {
|
||||
this[isEmpty ? 'bind' : 'update'] = definition
|
||||
} else {
|
||||
for (var prop in definition) {
|
||||
this[prop] = definition[prop]
|
||||
}
|
||||
}
|
||||
|
||||
// empty expression, we're done.
|
||||
if (isEmpty || this.isEmpty) {
|
||||
this.isEmpty = true
|
||||
return
|
||||
}
|
||||
|
||||
this.expression = (
|
||||
this.isLiteral
|
||||
? compiler.eval(this.expression)
|
||||
: this.expression
|
||||
).trim()
|
||||
|
||||
var filters = ast.filters,
|
||||
filter, fn, i, l, computed
|
||||
if (filters) {
|
||||
this.filters = []
|
||||
for (i = 0, l = filters.length; i < l; i++) {
|
||||
filter = filters[i]
|
||||
fn = this.compiler.getOption('filters', filter.name)
|
||||
if (fn) {
|
||||
filter.apply = fn
|
||||
this.filters.push(filter)
|
||||
if (fn.computed) {
|
||||
computed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.filters || !this.filters.length) {
|
||||
this.filters = null
|
||||
}
|
||||
|
||||
if (computed) {
|
||||
this.computedKey = Directive.inlineFilters(this.key, this.filters)
|
||||
this.filters = null
|
||||
}
|
||||
|
||||
this.isExp =
|
||||
computed ||
|
||||
!SINGLE_VAR_RE.test(this.key) ||
|
||||
NESTING_RE.test(this.key)
|
||||
|
||||
}
|
||||
|
||||
var DirProto = Directive.prototype
|
||||
|
||||
/**
|
||||
* called when a new value is set
|
||||
* for computed properties, this will only be called once
|
||||
* during initialization.
|
||||
*/
|
||||
DirProto.$update = function (value, init) {
|
||||
if (this.$lock) return
|
||||
if (init || value !== this.value || (value && typeof value === 'object')) {
|
||||
this.value = value
|
||||
if (this.update) {
|
||||
this.update(
|
||||
this.filters && !this.computeFilters
|
||||
? this.$applyFilters(value)
|
||||
: value,
|
||||
init
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pipe the value through filters
|
||||
*/
|
||||
DirProto.$applyFilters = function (value) {
|
||||
var filtered = value, filter
|
||||
for (var i = 0, l = this.filters.length; i < l; i++) {
|
||||
filter = this.filters[i]
|
||||
filtered = filter.apply.apply(this.vm, [filtered].concat(filter.args))
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbind diretive
|
||||
*/
|
||||
DirProto.$unbind = function () {
|
||||
// this can be called before the el is even assigned...
|
||||
if (!this.el || !this.vm) return
|
||||
if (this.unbind) this.unbind()
|
||||
this.vm = this.el = this.binding = this.compiler = null
|
||||
}
|
||||
|
||||
// Exposed static methods -----------------------------------------------------
|
||||
|
||||
/**
|
||||
* Parse a directive string into an Array of
|
||||
* AST-like objects representing directives
|
||||
*/
|
||||
Directive.parse = function (str) {
|
||||
|
||||
var inSingle = false,
|
||||
inDouble = false,
|
||||
curly = 0,
|
||||
square = 0,
|
||||
paren = 0,
|
||||
begin = 0,
|
||||
argIndex = 0,
|
||||
dirs = [],
|
||||
dir = {},
|
||||
lastFilterIndex = 0,
|
||||
arg
|
||||
|
||||
for (var c, i = 0, l = str.length; i < l; i++) {
|
||||
c = str.charAt(i)
|
||||
if (inSingle) {
|
||||
// check single quote
|
||||
if (c === "'") inSingle = !inSingle
|
||||
} else if (inDouble) {
|
||||
// check double quote
|
||||
if (c === '"') inDouble = !inDouble
|
||||
} else if (c === ',' && !paren && !curly && !square) {
|
||||
// reached the end of a directive
|
||||
pushDir()
|
||||
// reset & skip the comma
|
||||
dir = {}
|
||||
begin = argIndex = lastFilterIndex = i + 1
|
||||
} else if (c === ':' && !dir.key && !dir.arg) {
|
||||
// argument
|
||||
arg = str.slice(begin, i).trim()
|
||||
if (ARG_RE.test(arg)) {
|
||||
argIndex = i + 1
|
||||
dir.arg = str.slice(begin, i).trim()
|
||||
}
|
||||
} else if (c === '|' && str.charAt(i + 1) !== '|' && str.charAt(i - 1) !== '|') {
|
||||
if (dir.key === undefined) {
|
||||
// first filter, end of key
|
||||
lastFilterIndex = i + 1
|
||||
dir.key = str.slice(argIndex, i).trim()
|
||||
} else {
|
||||
// already has filter
|
||||
pushFilter()
|
||||
}
|
||||
} else if (c === '"') {
|
||||
inDouble = true
|
||||
} else if (c === "'") {
|
||||
inSingle = true
|
||||
} else if (c === '(') {
|
||||
paren++
|
||||
} else if (c === ')') {
|
||||
paren--
|
||||
} else if (c === '[') {
|
||||
square++
|
||||
} else if (c === ']') {
|
||||
square--
|
||||
} else if (c === '{') {
|
||||
curly++
|
||||
} else if (c === '}') {
|
||||
curly--
|
||||
}
|
||||
}
|
||||
if (i === 0 || begin !== i) {
|
||||
pushDir()
|
||||
}
|
||||
|
||||
function pushDir () {
|
||||
dir.expression = str.slice(begin, i).trim()
|
||||
if (dir.key === undefined) {
|
||||
dir.key = str.slice(argIndex, i).trim()
|
||||
} else if (lastFilterIndex !== begin) {
|
||||
pushFilter()
|
||||
}
|
||||
if (i === 0 || dir.key) {
|
||||
dirs.push(dir)
|
||||
}
|
||||
}
|
||||
|
||||
function pushFilter () {
|
||||
var exp = str.slice(lastFilterIndex, i).trim(),
|
||||
filter
|
||||
if (exp) {
|
||||
filter = {}
|
||||
var tokens = exp.match(FILTER_TOKEN_RE)
|
||||
filter.name = tokens[0]
|
||||
filter.args = tokens.length > 1 ? tokens.slice(1) : null
|
||||
}
|
||||
if (filter) {
|
||||
(dir.filters = dir.filters || []).push(filter)
|
||||
}
|
||||
lastFilterIndex = i + 1
|
||||
}
|
||||
|
||||
return dirs
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline computed filters so they become part
|
||||
* of the expression
|
||||
*/
|
||||
Directive.inlineFilters = function (key, filters) {
|
||||
var args, filter
|
||||
for (var i = 0, l = filters.length; i < l; i++) {
|
||||
filter = filters[i]
|
||||
args = filter.args
|
||||
? ',"' + filter.args.map(escapeQuote).join('","') + '"'
|
||||
: ''
|
||||
key = 'this.$compiler.getOption("filters", "' +
|
||||
filter.name +
|
||||
'").call(this,' +
|
||||
key + args +
|
||||
')'
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert double quotes to single quotes
|
||||
* so they don't mess up the generated function body
|
||||
*/
|
||||
function escapeQuote (v) {
|
||||
return v.indexOf('"') > -1
|
||||
? v.replace(QUOTE_RE, '\'')
|
||||
: v
|
||||
}
|
||||
|
||||
module.exports = Directive
|
41
vendor/assets/javascripts/bower/vue/src/directives/html.js
vendored
Normal file
41
vendor/assets/javascripts/bower/vue/src/directives/html.js
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
var utils = require('../utils'),
|
||||
slice = [].slice
|
||||
|
||||
/**
|
||||
* Binding for innerHTML
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
bind: function () {
|
||||
// a comment node means this is a binding for
|
||||
// {{{ inline unescaped html }}}
|
||||
if (this.el.nodeType === 8) {
|
||||
// hold nodes
|
||||
this.nodes = []
|
||||
}
|
||||
},
|
||||
|
||||
update: function (value) {
|
||||
value = utils.guard(value)
|
||||
if (this.nodes) {
|
||||
this.swap(value)
|
||||
} else {
|
||||
this.el.innerHTML = value
|
||||
}
|
||||
},
|
||||
|
||||
swap: function (value) {
|
||||
var parent = this.el.parentNode,
|
||||
nodes = this.nodes,
|
||||
i = nodes.length
|
||||
// remove old nodes
|
||||
while (i--) {
|
||||
parent.removeChild(nodes[i])
|
||||
}
|
||||
// convert new value to a fragment
|
||||
var frag = utils.toFragment(value)
|
||||
// save a reference to these nodes so we can remove later
|
||||
this.nodes = slice.call(frag.childNodes)
|
||||
parent.insertBefore(frag, this.el)
|
||||
}
|
||||
}
|
56
vendor/assets/javascripts/bower/vue/src/directives/if.js
vendored
Normal file
56
vendor/assets/javascripts/bower/vue/src/directives/if.js
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
var utils = require('../utils')
|
||||
|
||||
/**
|
||||
* Manages a conditional child VM
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
bind: function () {
|
||||
|
||||
this.parent = this.el.parentNode
|
||||
this.ref = document.createComment('vue-if')
|
||||
this.Ctor = this.compiler.resolveComponent(this.el)
|
||||
|
||||
// insert ref
|
||||
this.parent.insertBefore(this.ref, this.el)
|
||||
this.parent.removeChild(this.el)
|
||||
|
||||
if (utils.attr(this.el, 'view')) {
|
||||
utils.warn(
|
||||
'Conflict: v-if cannot be used together with v-view. ' +
|
||||
'Just set v-view\'s binding value to empty string to empty it.'
|
||||
)
|
||||
}
|
||||
if (utils.attr(this.el, 'repeat')) {
|
||||
utils.warn(
|
||||
'Conflict: v-if cannot be used together with v-repeat. ' +
|
||||
'Use `v-show` or the `filterBy` filter instead.'
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
update: function (value) {
|
||||
|
||||
if (!value) {
|
||||
this.unbind()
|
||||
} else if (!this.childVM) {
|
||||
this.childVM = new this.Ctor({
|
||||
el: this.el.cloneNode(true),
|
||||
parent: this.vm
|
||||
})
|
||||
if (this.compiler.init) {
|
||||
this.parent.insertBefore(this.childVM.$el, this.ref)
|
||||
} else {
|
||||
this.childVM.$before(this.ref)
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
unbind: function () {
|
||||
if (this.childVM) {
|
||||
this.childVM.$destroy()
|
||||
this.childVM = null
|
||||
}
|
||||
}
|
||||
}
|
129
vendor/assets/javascripts/bower/vue/src/directives/index.js
vendored
Normal file
129
vendor/assets/javascripts/bower/vue/src/directives/index.js
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
var utils = require('../utils'),
|
||||
config = require('../config'),
|
||||
transition = require('../transition'),
|
||||
directives = module.exports = utils.hash()
|
||||
|
||||
/**
|
||||
* Nest and manage a Child VM
|
||||
*/
|
||||
directives.component = {
|
||||
isLiteral: true,
|
||||
bind: function () {
|
||||
if (!this.el.vue_vm) {
|
||||
this.childVM = new this.Ctor({
|
||||
el: this.el,
|
||||
parent: this.vm
|
||||
})
|
||||
}
|
||||
},
|
||||
unbind: function () {
|
||||
if (this.childVM) {
|
||||
this.childVM.$destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binding HTML attributes
|
||||
*/
|
||||
directives.attr = {
|
||||
bind: function () {
|
||||
var params = this.vm.$options.paramAttributes
|
||||
this.isParam = params && params.indexOf(this.arg) > -1
|
||||
},
|
||||
update: function (value) {
|
||||
if (value || value === 0) {
|
||||
this.el.setAttribute(this.arg, value)
|
||||
} else {
|
||||
this.el.removeAttribute(this.arg)
|
||||
}
|
||||
if (this.isParam) {
|
||||
this.vm[this.arg] = utils.checkNumber(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binding textContent
|
||||
*/
|
||||
directives.text = {
|
||||
bind: function () {
|
||||
this.attr = this.el.nodeType === 3
|
||||
? 'nodeValue'
|
||||
: 'textContent'
|
||||
},
|
||||
update: function (value) {
|
||||
this.el[this.attr] = utils.guard(value)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binding CSS display property
|
||||
*/
|
||||
directives.show = function (value) {
|
||||
var el = this.el,
|
||||
target = value ? '' : 'none',
|
||||
change = function () {
|
||||
el.style.display = target
|
||||
}
|
||||
transition(el, value ? 1 : -1, change, this.compiler)
|
||||
}
|
||||
|
||||
/**
|
||||
* Binding CSS classes
|
||||
*/
|
||||
directives['class'] = function (value) {
|
||||
if (this.arg) {
|
||||
utils[value ? 'addClass' : 'removeClass'](this.el, this.arg)
|
||||
} else {
|
||||
if (this.lastVal) {
|
||||
utils.removeClass(this.el, this.lastVal)
|
||||
}
|
||||
if (value) {
|
||||
utils.addClass(this.el, value)
|
||||
this.lastVal = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only removed after the owner VM is ready
|
||||
*/
|
||||
directives.cloak = {
|
||||
isEmpty: true,
|
||||
bind: function () {
|
||||
var el = this.el
|
||||
this.compiler.observer.once('hook:ready', function () {
|
||||
el.removeAttribute(config.prefix + '-cloak')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a reference to self in parent VM's $
|
||||
*/
|
||||
directives.ref = {
|
||||
isLiteral: true,
|
||||
bind: function () {
|
||||
var id = this.expression
|
||||
if (id) {
|
||||
this.vm.$parent.$[id] = this.vm
|
||||
}
|
||||
},
|
||||
unbind: function () {
|
||||
var id = this.expression
|
||||
if (id) {
|
||||
delete this.vm.$parent.$[id]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
directives.on = require('./on')
|
||||
directives.repeat = require('./repeat')
|
||||
directives.model = require('./model')
|
||||
directives['if'] = require('./if')
|
||||
directives['with'] = require('./with')
|
||||
directives.html = require('./html')
|
||||
directives.style = require('./style')
|
||||
directives.partial = require('./partial')
|
||||
directives.view = require('./view')
|
174
vendor/assets/javascripts/bower/vue/src/directives/model.js
vendored
Normal file
174
vendor/assets/javascripts/bower/vue/src/directives/model.js
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
var utils = require('../utils'),
|
||||
isIE9 = navigator.userAgent.indexOf('MSIE 9.0') > 0,
|
||||
filter = [].filter
|
||||
|
||||
/**
|
||||
* Returns an array of values from a multiple select
|
||||
*/
|
||||
function getMultipleSelectOptions (select) {
|
||||
return filter
|
||||
.call(select.options, function (option) {
|
||||
return option.selected
|
||||
})
|
||||
.map(function (option) {
|
||||
return option.value || option.text
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Two-way binding for form input elements
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
bind: function () {
|
||||
|
||||
var self = this,
|
||||
el = self.el,
|
||||
type = el.type,
|
||||
tag = el.tagName
|
||||
|
||||
self.lock = false
|
||||
self.ownerVM = self.binding.compiler.vm
|
||||
|
||||
// determine what event to listen to
|
||||
self.event =
|
||||
(self.compiler.options.lazy ||
|
||||
tag === 'SELECT' ||
|
||||
type === 'checkbox' || type === 'radio')
|
||||
? 'change'
|
||||
: 'input'
|
||||
|
||||
// determine the attribute to change when updating
|
||||
self.attr = type === 'checkbox'
|
||||
? 'checked'
|
||||
: (tag === 'INPUT' || tag === 'SELECT' || tag === 'TEXTAREA')
|
||||
? 'value'
|
||||
: 'innerHTML'
|
||||
|
||||
// select[multiple] support
|
||||
if(tag === 'SELECT' && el.hasAttribute('multiple')) {
|
||||
this.multi = true
|
||||
}
|
||||
|
||||
var compositionLock = false
|
||||
self.cLock = function () {
|
||||
compositionLock = true
|
||||
}
|
||||
self.cUnlock = function () {
|
||||
compositionLock = false
|
||||
}
|
||||
el.addEventListener('compositionstart', this.cLock)
|
||||
el.addEventListener('compositionend', this.cUnlock)
|
||||
|
||||
// attach listener
|
||||
self.set = self.filters
|
||||
? function () {
|
||||
if (compositionLock) return
|
||||
// if this directive has filters
|
||||
// we need to let the vm.$set trigger
|
||||
// update() so filters are applied.
|
||||
// therefore we have to record cursor position
|
||||
// so that after vm.$set changes the input
|
||||
// value we can put the cursor back at where it is
|
||||
var cursorPos
|
||||
try { cursorPos = el.selectionStart } catch (e) {}
|
||||
|
||||
self._set()
|
||||
|
||||
// since updates are async
|
||||
// we need to reset cursor position async too
|
||||
utils.nextTick(function () {
|
||||
if (cursorPos !== undefined) {
|
||||
el.setSelectionRange(cursorPos, cursorPos)
|
||||
}
|
||||
})
|
||||
}
|
||||
: function () {
|
||||
if (compositionLock) return
|
||||
// no filters, don't let it trigger update()
|
||||
self.lock = true
|
||||
|
||||
self._set()
|
||||
|
||||
utils.nextTick(function () {
|
||||
self.lock = false
|
||||
})
|
||||
}
|
||||
el.addEventListener(self.event, self.set)
|
||||
|
||||
// fix shit for IE9
|
||||
// since it doesn't fire input on backspace / del / cut
|
||||
if (isIE9) {
|
||||
self.onCut = function () {
|
||||
// cut event fires before the value actually changes
|
||||
utils.nextTick(function () {
|
||||
self.set()
|
||||
})
|
||||
}
|
||||
self.onDel = function (e) {
|
||||
if (e.keyCode === 46 || e.keyCode === 8) {
|
||||
self.set()
|
||||
}
|
||||
}
|
||||
el.addEventListener('cut', self.onCut)
|
||||
el.addEventListener('keyup', self.onDel)
|
||||
}
|
||||
},
|
||||
|
||||
_set: function () {
|
||||
this.ownerVM.$set(
|
||||
this.key, this.multi
|
||||
? getMultipleSelectOptions(this.el)
|
||||
: this.el[this.attr]
|
||||
)
|
||||
},
|
||||
|
||||
update: function (value, init) {
|
||||
/* jshint eqeqeq: false */
|
||||
// sync back inline value if initial data is undefined
|
||||
if (init && value === undefined) {
|
||||
return this._set()
|
||||
}
|
||||
if (this.lock) return
|
||||
var el = this.el
|
||||
if (el.tagName === 'SELECT') { // select dropdown
|
||||
el.selectedIndex = -1
|
||||
if(this.multi && Array.isArray(value)) {
|
||||
value.forEach(this.updateSelect, this)
|
||||
} else {
|
||||
this.updateSelect(value)
|
||||
}
|
||||
} else if (el.type === 'radio') { // radio button
|
||||
el.checked = value == el.value
|
||||
} else if (el.type === 'checkbox') { // checkbox
|
||||
el.checked = !!value
|
||||
} else {
|
||||
el[this.attr] = utils.guard(value)
|
||||
}
|
||||
},
|
||||
|
||||
updateSelect: function (value) {
|
||||
/* jshint eqeqeq: false */
|
||||
// setting <select>'s value in IE9 doesn't work
|
||||
// we have to manually loop through the options
|
||||
var options = this.el.options,
|
||||
i = options.length
|
||||
while (i--) {
|
||||
if (options[i].value == value) {
|
||||
options[i].selected = true
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
unbind: function () {
|
||||
var el = this.el
|
||||
el.removeEventListener(this.event, this.set)
|
||||
el.removeEventListener('compositionstart', this.cLock)
|
||||
el.removeEventListener('compositionend', this.cUnlock)
|
||||
if (isIE9) {
|
||||
el.removeEventListener('cut', this.onCut)
|
||||
el.removeEventListener('keyup', this.onDel)
|
||||
}
|
||||
}
|
||||
}
|
37
vendor/assets/javascripts/bower/vue/src/directives/on.js
vendored
Normal file
37
vendor/assets/javascripts/bower/vue/src/directives/on.js
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
var utils = require('../utils')
|
||||
|
||||
/**
|
||||
* Binding for event listeners
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
isFn: true,
|
||||
|
||||
bind: function () {
|
||||
this.context = this.binding.isExp
|
||||
? this.vm
|
||||
: this.binding.compiler.vm
|
||||
},
|
||||
|
||||
update: function (handler) {
|
||||
if (typeof handler !== 'function') {
|
||||
utils.warn('Directive "v-on:' + this.expression + '" expects a method.')
|
||||
return
|
||||
}
|
||||
this.unbind()
|
||||
var vm = this.vm,
|
||||
context = this.context
|
||||
this.handler = function (e) {
|
||||
e.targetVM = vm
|
||||
context.$event = e
|
||||
var res = handler.call(context, e)
|
||||
context.$event = null
|
||||
return res
|
||||
}
|
||||
this.el.addEventListener(this.arg, this.handler)
|
||||
},
|
||||
|
||||
unbind: function () {
|
||||
this.el.removeEventListener(this.arg, this.handler)
|
||||
}
|
||||
}
|
50
vendor/assets/javascripts/bower/vue/src/directives/partial.js
vendored
Normal file
50
vendor/assets/javascripts/bower/vue/src/directives/partial.js
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
var utils = require('../utils')
|
||||
|
||||
/**
|
||||
* Binding for partials
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
isLiteral: true,
|
||||
|
||||
bind: function () {
|
||||
|
||||
var id = this.expression
|
||||
if (!id) return
|
||||
|
||||
var el = this.el,
|
||||
compiler = this.compiler,
|
||||
partial = compiler.getOption('partials', id)
|
||||
|
||||
if (!partial) {
|
||||
if (id === 'yield') {
|
||||
utils.warn('{{>yield}} syntax has been deprecated. Use <content> tag instead.')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
partial = partial.cloneNode(true)
|
||||
|
||||
// comment ref node means inline partial
|
||||
if (el.nodeType === 8) {
|
||||
|
||||
// keep a ref for the partial's content nodes
|
||||
var nodes = [].slice.call(partial.childNodes),
|
||||
parent = el.parentNode
|
||||
parent.insertBefore(partial, el)
|
||||
parent.removeChild(el)
|
||||
// compile partial after appending, because its children's parentNode
|
||||
// will change from the fragment to the correct parentNode.
|
||||
// This could affect directives that need access to its element's parentNode.
|
||||
nodes.forEach(compiler.compile, compiler)
|
||||
|
||||
} else {
|
||||
|
||||
// just set innerHTML...
|
||||
el.innerHTML = ''
|
||||
el.appendChild(partial.cloneNode(true))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
246
vendor/assets/javascripts/bower/vue/src/directives/repeat.js
vendored
Normal file
246
vendor/assets/javascripts/bower/vue/src/directives/repeat.js
vendored
Normal file
@ -0,0 +1,246 @@
|
||||
var utils = require('../utils'),
|
||||
config = require('../config')
|
||||
|
||||
/**
|
||||
* Binding that manages VMs based on an Array
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
bind: function () {
|
||||
|
||||
this.identifier = '$r' + this.id
|
||||
|
||||
// a hash to cache the same expressions on repeated instances
|
||||
// so they don't have to be compiled for every single instance
|
||||
this.expCache = utils.hash()
|
||||
|
||||
var el = this.el,
|
||||
ctn = this.container = el.parentNode
|
||||
|
||||
// extract child Id, if any
|
||||
this.childId = this.compiler.eval(utils.attr(el, 'ref'))
|
||||
|
||||
// create a comment node as a reference node for DOM insertions
|
||||
this.ref = document.createComment(config.prefix + '-repeat-' + this.key)
|
||||
ctn.insertBefore(this.ref, el)
|
||||
ctn.removeChild(el)
|
||||
|
||||
this.collection = null
|
||||
this.vms = null
|
||||
|
||||
},
|
||||
|
||||
update: function (collection) {
|
||||
|
||||
if (!Array.isArray(collection)) {
|
||||
if (utils.isObject(collection)) {
|
||||
collection = utils.objectToArray(collection)
|
||||
} else {
|
||||
utils.warn('v-repeat only accepts Array or Object values.')
|
||||
}
|
||||
}
|
||||
|
||||
// keep reference of old data and VMs
|
||||
// so we can reuse them if possible
|
||||
this.oldVMs = this.vms
|
||||
this.oldCollection = this.collection
|
||||
collection = this.collection = collection || []
|
||||
|
||||
var isObject = collection[0] && utils.isObject(collection[0])
|
||||
this.vms = this.oldCollection
|
||||
? this.diff(collection, isObject)
|
||||
: this.init(collection, isObject)
|
||||
|
||||
if (this.childId) {
|
||||
this.vm.$[this.childId] = this.vms
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
init: function (collection, isObject) {
|
||||
var vm, vms = []
|
||||
for (var i = 0, l = collection.length; i < l; i++) {
|
||||
vm = this.build(collection[i], i, isObject)
|
||||
vms.push(vm)
|
||||
if (this.compiler.init) {
|
||||
this.container.insertBefore(vm.$el, this.ref)
|
||||
} else {
|
||||
vm.$before(this.ref)
|
||||
}
|
||||
}
|
||||
return vms
|
||||
},
|
||||
|
||||
/**
|
||||
* Diff the new array with the old
|
||||
* and determine the minimum amount of DOM manipulations.
|
||||
*/
|
||||
diff: function (newCollection, isObject) {
|
||||
|
||||
var i, l, item, vm,
|
||||
oldIndex,
|
||||
targetNext,
|
||||
currentNext,
|
||||
nextEl,
|
||||
ctn = this.container,
|
||||
oldVMs = this.oldVMs,
|
||||
vms = []
|
||||
|
||||
vms.length = newCollection.length
|
||||
|
||||
// first pass, collect new reused and new created
|
||||
for (i = 0, l = newCollection.length; i < l; i++) {
|
||||
item = newCollection[i]
|
||||
if (isObject) {
|
||||
item.$index = i
|
||||
if (item.__emitter__ && item.__emitter__[this.identifier]) {
|
||||
// this piece of data is being reused.
|
||||
// record its final position in reused vms
|
||||
item.$reused = true
|
||||
} else {
|
||||
vms[i] = this.build(item, i, isObject)
|
||||
}
|
||||
} else {
|
||||
// we can't attach an identifier to primitive values
|
||||
// so have to do an indexOf...
|
||||
oldIndex = indexOf(oldVMs, item)
|
||||
if (oldIndex > -1) {
|
||||
// record the position on the existing vm
|
||||
oldVMs[oldIndex].$reused = true
|
||||
oldVMs[oldIndex].$data.$index = i
|
||||
} else {
|
||||
vms[i] = this.build(item, i, isObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// second pass, collect old reused and destroy unused
|
||||
for (i = 0, l = oldVMs.length; i < l; i++) {
|
||||
vm = oldVMs[i]
|
||||
item = this.arg
|
||||
? vm.$data[this.arg]
|
||||
: vm.$data
|
||||
if (item.$reused) {
|
||||
vm.$reused = true
|
||||
delete item.$reused
|
||||
}
|
||||
if (vm.$reused) {
|
||||
// update the index to latest
|
||||
vm.$index = item.$index
|
||||
// the item could have had a new key
|
||||
if (item.$key && item.$key !== vm.$key) {
|
||||
vm.$key = item.$key
|
||||
}
|
||||
vms[vm.$index] = vm
|
||||
} else {
|
||||
// this one can be destroyed.
|
||||
if (item.__emitter__) {
|
||||
delete item.__emitter__[this.identifier]
|
||||
}
|
||||
vm.$destroy()
|
||||
}
|
||||
}
|
||||
|
||||
// final pass, move/insert DOM elements
|
||||
i = vms.length
|
||||
while (i--) {
|
||||
vm = vms[i]
|
||||
item = vm.$data
|
||||
targetNext = vms[i + 1]
|
||||
if (vm.$reused) {
|
||||
nextEl = vm.$el.nextSibling
|
||||
// destroyed VMs' element might still be in the DOM
|
||||
// due to transitions
|
||||
while (!nextEl.vue_vm && nextEl !== this.ref) {
|
||||
nextEl = nextEl.nextSibling
|
||||
}
|
||||
currentNext = nextEl.vue_vm
|
||||
if (currentNext !== targetNext) {
|
||||
if (!targetNext) {
|
||||
ctn.insertBefore(vm.$el, this.ref)
|
||||
} else {
|
||||
nextEl = targetNext.$el
|
||||
// new VMs' element might not be in the DOM yet
|
||||
// due to transitions
|
||||
while (!nextEl.parentNode) {
|
||||
targetNext = vms[nextEl.vue_vm.$index + 1]
|
||||
nextEl = targetNext
|
||||
? targetNext.$el
|
||||
: this.ref
|
||||
}
|
||||
ctn.insertBefore(vm.$el, nextEl)
|
||||
}
|
||||
}
|
||||
delete vm.$reused
|
||||
delete item.$index
|
||||
delete item.$key
|
||||
} else { // a new vm
|
||||
vm.$before(targetNext ? targetNext.$el : this.ref)
|
||||
}
|
||||
}
|
||||
|
||||
return vms
|
||||
},
|
||||
|
||||
build: function (data, index, isObject) {
|
||||
|
||||
// wrap non-object values
|
||||
var raw, alias,
|
||||
wrap = !isObject || this.arg
|
||||
if (wrap) {
|
||||
raw = data
|
||||
alias = this.arg || '$value'
|
||||
data = {}
|
||||
data[alias] = raw
|
||||
}
|
||||
data.$index = index
|
||||
|
||||
var el = this.el.cloneNode(true),
|
||||
Ctor = this.compiler.resolveComponent(el, data),
|
||||
vm = new Ctor({
|
||||
el: el,
|
||||
data: data,
|
||||
parent: this.vm,
|
||||
compilerOptions: {
|
||||
repeat: true,
|
||||
expCache: this.expCache
|
||||
}
|
||||
})
|
||||
|
||||
if (isObject) {
|
||||
// attach an ienumerable identifier to the raw data
|
||||
(raw || data).__emitter__[this.identifier] = true
|
||||
}
|
||||
|
||||
return vm
|
||||
|
||||
},
|
||||
|
||||
unbind: function () {
|
||||
if (this.childId) {
|
||||
delete this.vm.$[this.childId]
|
||||
}
|
||||
if (this.vms) {
|
||||
var i = this.vms.length
|
||||
while (i--) {
|
||||
this.vms[i].$destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Find an object or a wrapped data object
|
||||
* from an Array
|
||||
*/
|
||||
function indexOf (vms, obj) {
|
||||
for (var vm, i = 0, l = vms.length; i < l; i++) {
|
||||
vm = vms[i]
|
||||
if (!vm.$reused && vm.$value === obj) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
44
vendor/assets/javascripts/bower/vue/src/directives/style.js
vendored
Normal file
44
vendor/assets/javascripts/bower/vue/src/directives/style.js
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
var camelRE = /-([a-z])/g,
|
||||
prefixes = ['webkit', 'moz', 'ms']
|
||||
|
||||
function camelReplacer (m) {
|
||||
return m[1].toUpperCase()
|
||||
}
|
||||
|
||||
/**
|
||||
* Binding for CSS styles
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
bind: function () {
|
||||
var prop = this.arg
|
||||
if (!prop) return
|
||||
var first = prop.charAt(0)
|
||||
if (first === '$') {
|
||||
// properties that start with $ will be auto-prefixed
|
||||
prop = prop.slice(1)
|
||||
this.prefixed = true
|
||||
} else if (first === '-') {
|
||||
// normal starting hyphens should not be converted
|
||||
prop = prop.slice(1)
|
||||
}
|
||||
this.prop = prop.replace(camelRE, camelReplacer)
|
||||
},
|
||||
|
||||
update: function (value) {
|
||||
var prop = this.prop
|
||||
if (prop) {
|
||||
this.el.style[prop] = value
|
||||
if (this.prefixed) {
|
||||
prop = prop.charAt(0).toUpperCase() + prop.slice(1)
|
||||
var i = prefixes.length
|
||||
while (i--) {
|
||||
this.el.style[prefixes[i] + prop] = value
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.el.style.cssText = value
|
||||
}
|
||||
}
|
||||
|
||||
}
|
56
vendor/assets/javascripts/bower/vue/src/directives/view.js
vendored
Normal file
56
vendor/assets/javascripts/bower/vue/src/directives/view.js
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Manages a conditional child VM using the
|
||||
* binding's value as the component ID.
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
bind: function () {
|
||||
|
||||
// track position in DOM with a ref node
|
||||
var el = this.raw = this.el,
|
||||
parent = el.parentNode,
|
||||
ref = this.ref = document.createComment('v-view')
|
||||
parent.insertBefore(ref, el)
|
||||
parent.removeChild(el)
|
||||
|
||||
// cache original content
|
||||
/* jshint boss: true */
|
||||
var node,
|
||||
frag = this.inner = document.createElement('div')
|
||||
while (node = el.firstChild) {
|
||||
frag.appendChild(node)
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
update: function(value) {
|
||||
|
||||
this.unbind()
|
||||
|
||||
var Ctor = this.compiler.getOption('components', value)
|
||||
if (!Ctor) return
|
||||
|
||||
this.childVM = new Ctor({
|
||||
el: this.raw.cloneNode(true),
|
||||
parent: this.vm,
|
||||
compilerOptions: {
|
||||
rawContent: this.inner.cloneNode(true)
|
||||
}
|
||||
})
|
||||
|
||||
this.el = this.childVM.$el
|
||||
if (this.compiler.init) {
|
||||
this.ref.parentNode.insertBefore(this.el, this.ref)
|
||||
} else {
|
||||
this.childVM.$before(this.ref)
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
unbind: function() {
|
||||
if (this.childVM) {
|
||||
this.childVM.$destroy()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
50
vendor/assets/javascripts/bower/vue/src/directives/with.js
vendored
Normal file
50
vendor/assets/javascripts/bower/vue/src/directives/with.js
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
var utils = require('../utils')
|
||||
|
||||
/**
|
||||
* Binding for inheriting data from parent VMs.
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
bind: function () {
|
||||
|
||||
var self = this,
|
||||
childKey = self.arg,
|
||||
parentKey = self.key,
|
||||
compiler = self.compiler,
|
||||
owner = self.binding.compiler
|
||||
|
||||
if (compiler === owner) {
|
||||
this.alone = true
|
||||
return
|
||||
}
|
||||
|
||||
if (childKey) {
|
||||
if (!compiler.bindings[childKey]) {
|
||||
compiler.createBinding(childKey)
|
||||
}
|
||||
// sync changes on child back to parent
|
||||
compiler.observer.on('change:' + childKey, function (val) {
|
||||
if (compiler.init) return
|
||||
if (!self.lock) {
|
||||
self.lock = true
|
||||
utils.nextTick(function () {
|
||||
self.lock = false
|
||||
})
|
||||
}
|
||||
owner.vm.$set(parentKey, val)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
update: function (value) {
|
||||
// sync from parent
|
||||
if (!this.alone && !this.lock) {
|
||||
if (this.arg) {
|
||||
this.vm.$set(this.arg, value)
|
||||
} else {
|
||||
this.vm.$data = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
97
vendor/assets/javascripts/bower/vue/src/emitter.js
vendored
Normal file
97
vendor/assets/javascripts/bower/vue/src/emitter.js
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
var slice = [].slice
|
||||
|
||||
function Emitter (ctx) {
|
||||
this._ctx = ctx || this
|
||||
}
|
||||
|
||||
var EmitterProto = Emitter.prototype
|
||||
|
||||
EmitterProto.on = function (event, fn) {
|
||||
this._cbs = this._cbs || {}
|
||||
;(this._cbs[event] = this._cbs[event] || [])
|
||||
.push(fn)
|
||||
return this
|
||||
}
|
||||
|
||||
EmitterProto.once = function (event, fn) {
|
||||
var self = this
|
||||
this._cbs = this._cbs || {}
|
||||
|
||||
function on () {
|
||||
self.off(event, on)
|
||||
fn.apply(this, arguments)
|
||||
}
|
||||
|
||||
on.fn = fn
|
||||
this.on(event, on)
|
||||
return this
|
||||
}
|
||||
|
||||
EmitterProto.off = function (event, fn) {
|
||||
this._cbs = this._cbs || {}
|
||||
|
||||
// all
|
||||
if (!arguments.length) {
|
||||
this._cbs = {}
|
||||
return this
|
||||
}
|
||||
|
||||
// specific event
|
||||
var callbacks = this._cbs[event]
|
||||
if (!callbacks) return this
|
||||
|
||||
// remove all handlers
|
||||
if (arguments.length === 1) {
|
||||
delete this._cbs[event]
|
||||
return this
|
||||
}
|
||||
|
||||
// remove specific handler
|
||||
var cb
|
||||
for (var i = 0; i < callbacks.length; i++) {
|
||||
cb = callbacks[i]
|
||||
if (cb === fn || cb.fn === fn) {
|
||||
callbacks.splice(i, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* The internal, faster emit with fixed amount of arguments
|
||||
* using Function.call
|
||||
*/
|
||||
EmitterProto.emit = function (event, a, b, c) {
|
||||
this._cbs = this._cbs || {}
|
||||
var callbacks = this._cbs[event]
|
||||
|
||||
if (callbacks) {
|
||||
callbacks = callbacks.slice(0)
|
||||
for (var i = 0, len = callbacks.length; i < len; i++) {
|
||||
callbacks[i].call(this._ctx, a, b, c)
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* The external emit using Function.apply
|
||||
*/
|
||||
EmitterProto.applyEmit = function (event) {
|
||||
this._cbs = this._cbs || {}
|
||||
var callbacks = this._cbs[event], args
|
||||
|
||||
if (callbacks) {
|
||||
callbacks = callbacks.slice(0)
|
||||
args = slice.call(arguments, 1)
|
||||
for (var i = 0, len = callbacks.length; i < len; i++) {
|
||||
callbacks[i].apply(this._ctx, args)
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
module.exports = Emitter
|
190
vendor/assets/javascripts/bower/vue/src/exp-parser.js
vendored
Normal file
190
vendor/assets/javascripts/bower/vue/src/exp-parser.js
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
var utils = require('./utils'),
|
||||
STR_SAVE_RE = /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,
|
||||
STR_RESTORE_RE = /"(\d+)"/g,
|
||||
NEWLINE_RE = /\n/g,
|
||||
CTOR_RE = new RegExp('constructor'.split('').join('[\'"+, ]*')),
|
||||
UNICODE_RE = /\\u\d\d\d\d/
|
||||
|
||||
// Variable extraction scooped from https://github.com/RubyLouvre/avalon
|
||||
|
||||
var KEYWORDS =
|
||||
// keywords
|
||||
'break,case,catch,continue,debugger,default,delete,do,else,false' +
|
||||
',finally,for,function,if,in,instanceof,new,null,return,switch,this' +
|
||||
',throw,true,try,typeof,var,void,while,with,undefined' +
|
||||
// reserved
|
||||
',abstract,boolean,byte,char,class,const,double,enum,export,extends' +
|
||||
',final,float,goto,implements,import,int,interface,long,native' +
|
||||
',package,private,protected,public,short,static,super,synchronized' +
|
||||
',throws,transient,volatile' +
|
||||
// ECMA 5 - use strict
|
||||
',arguments,let,yield' +
|
||||
// allow using Math in expressions
|
||||
',Math',
|
||||
|
||||
KEYWORDS_RE = new RegExp(["\\b" + KEYWORDS.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g'),
|
||||
REMOVE_RE = /\/\*(?:.|\n)*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|'[^']*'|"[^"]*"|[\s\t\n]*\.[\s\t\n]*[$\w\.]+|[\{,]\s*[\w\$_]+\s*:/g,
|
||||
SPLIT_RE = /[^\w$]+/g,
|
||||
NUMBER_RE = /\b\d[^,]*/g,
|
||||
BOUNDARY_RE = /^,+|,+$/g
|
||||
|
||||
/**
|
||||
* Strip top level variable names from a snippet of JS expression
|
||||
*/
|
||||
function getVariables (code) {
|
||||
code = code
|
||||
.replace(REMOVE_RE, '')
|
||||
.replace(SPLIT_RE, ',')
|
||||
.replace(KEYWORDS_RE, '')
|
||||
.replace(NUMBER_RE, '')
|
||||
.replace(BOUNDARY_RE, '')
|
||||
return code
|
||||
? code.split(/,+/)
|
||||
: []
|
||||
}
|
||||
|
||||
/**
|
||||
* A given path could potentially exist not on the
|
||||
* current compiler, but up in the parent chain somewhere.
|
||||
* This function generates an access relationship string
|
||||
* that can be used in the getter function by walking up
|
||||
* the parent chain to check for key existence.
|
||||
*
|
||||
* It stops at top parent if no vm in the chain has the
|
||||
* key. It then creates any missing bindings on the
|
||||
* final resolved vm.
|
||||
*/
|
||||
function traceScope (path, compiler, data) {
|
||||
var rel = '',
|
||||
dist = 0,
|
||||
self = compiler
|
||||
|
||||
if (data && utils.get(data, path) !== undefined) {
|
||||
// hack: temporarily attached data
|
||||
return '$temp.'
|
||||
}
|
||||
|
||||
while (compiler) {
|
||||
if (compiler.hasKey(path)) {
|
||||
break
|
||||
} else {
|
||||
compiler = compiler.parent
|
||||
dist++
|
||||
}
|
||||
}
|
||||
if (compiler) {
|
||||
while (dist--) {
|
||||
rel += '$parent.'
|
||||
}
|
||||
if (!compiler.bindings[path] && path.charAt(0) !== '$') {
|
||||
compiler.createBinding(path)
|
||||
}
|
||||
} else {
|
||||
self.createBinding(path)
|
||||
}
|
||||
return rel
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a function from a string...
|
||||
* this looks like evil magic but since all variables are limited
|
||||
* to the VM's data it's actually properly sandboxed
|
||||
*/
|
||||
function makeGetter (exp, raw) {
|
||||
var fn
|
||||
try {
|
||||
fn = new Function(exp)
|
||||
} catch (e) {
|
||||
utils.warn('Error parsing expression: ' + raw)
|
||||
}
|
||||
return fn
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape a leading dollar sign for regex construction
|
||||
*/
|
||||
function escapeDollar (v) {
|
||||
return v.charAt(0) === '$'
|
||||
? '\\' + v
|
||||
: v
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and return an anonymous computed property getter function
|
||||
* from an arbitrary expression, together with a list of paths to be
|
||||
* created as bindings.
|
||||
*/
|
||||
exports.parse = function (exp, compiler, data) {
|
||||
// unicode and 'constructor' are not allowed for XSS security.
|
||||
if (UNICODE_RE.test(exp) || CTOR_RE.test(exp)) {
|
||||
utils.warn('Unsafe expression: ' + exp)
|
||||
return
|
||||
}
|
||||
// extract variable names
|
||||
var vars = getVariables(exp)
|
||||
if (!vars.length) {
|
||||
return makeGetter('return ' + exp, exp)
|
||||
}
|
||||
vars = utils.unique(vars)
|
||||
|
||||
var accessors = '',
|
||||
has = utils.hash(),
|
||||
strings = [],
|
||||
// construct a regex to extract all valid variable paths
|
||||
// ones that begin with "$" are particularly tricky
|
||||
// because we can't use \b for them
|
||||
pathRE = new RegExp(
|
||||
"[^$\\w\\.](" +
|
||||
vars.map(escapeDollar).join('|') +
|
||||
")[$\\w\\.]*\\b", 'g'
|
||||
),
|
||||
body = (' ' + exp)
|
||||
.replace(STR_SAVE_RE, saveStrings)
|
||||
.replace(pathRE, replacePath)
|
||||
.replace(STR_RESTORE_RE, restoreStrings)
|
||||
|
||||
body = accessors + 'return ' + body
|
||||
|
||||
function saveStrings (str) {
|
||||
var i = strings.length
|
||||
// escape newlines in strings so the expression
|
||||
// can be correctly evaluated
|
||||
strings[i] = str.replace(NEWLINE_RE, '\\n')
|
||||
return '"' + i + '"'
|
||||
}
|
||||
|
||||
function replacePath (path) {
|
||||
// keep track of the first char
|
||||
var c = path.charAt(0)
|
||||
path = path.slice(1)
|
||||
var val = 'this.' + traceScope(path, compiler, data) + path
|
||||
if (!has[path]) {
|
||||
accessors += val + ';'
|
||||
has[path] = 1
|
||||
}
|
||||
// don't forget to put that first char back
|
||||
return c + val
|
||||
}
|
||||
|
||||
function restoreStrings (str, i) {
|
||||
return strings[i]
|
||||
}
|
||||
|
||||
return makeGetter(body, exp)
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate an expression in the context of a compiler.
|
||||
* Accepts additional data.
|
||||
*/
|
||||
exports.eval = function (exp, compiler, data) {
|
||||
var getter = exports.parse(exp, compiler, data), res
|
||||
if (getter) {
|
||||
// hack: temporarily attach the additional data so
|
||||
// it can be accessed in the getter
|
||||
compiler.vm.$temp = data
|
||||
res = getter.call(compiler.vm)
|
||||
delete compiler.vm.$temp
|
||||
}
|
||||
return res
|
||||
}
|
190
vendor/assets/javascripts/bower/vue/src/filters.js
vendored
Normal file
190
vendor/assets/javascripts/bower/vue/src/filters.js
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
var utils = require('./utils'),
|
||||
get = utils.get,
|
||||
slice = [].slice,
|
||||
QUOTE_RE = /^'.*'$/,
|
||||
filters = module.exports = utils.hash()
|
||||
|
||||
/**
|
||||
* 'abc' => 'Abc'
|
||||
*/
|
||||
filters.capitalize = function (value) {
|
||||
if (!value && value !== 0) return ''
|
||||
value = value.toString()
|
||||
return value.charAt(0).toUpperCase() + value.slice(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* 'abc' => 'ABC'
|
||||
*/
|
||||
filters.uppercase = function (value) {
|
||||
return (value || value === 0)
|
||||
? value.toString().toUpperCase()
|
||||
: ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 'AbC' => 'abc'
|
||||
*/
|
||||
filters.lowercase = function (value) {
|
||||
return (value || value === 0)
|
||||
? value.toString().toLowerCase()
|
||||
: ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 12345 => $12,345.00
|
||||
*/
|
||||
filters.currency = function (value, sign) {
|
||||
if (!value && value !== 0) return ''
|
||||
sign = sign || '$'
|
||||
var s = Math.floor(value).toString(),
|
||||
i = s.length % 3,
|
||||
h = i > 0 ? (s.slice(0, i) + (s.length > 3 ? ',' : '')) : '',
|
||||
f = '.' + value.toFixed(2).slice(-2)
|
||||
return sign + h + s.slice(i).replace(/(\d{3})(?=\d)/g, '$1,') + f
|
||||
}
|
||||
|
||||
/**
|
||||
* args: an array of strings corresponding to
|
||||
* the single, double, triple ... forms of the word to
|
||||
* be pluralized. When the number to be pluralized
|
||||
* exceeds the length of the args, it will use the last
|
||||
* entry in the array.
|
||||
*
|
||||
* e.g. ['single', 'double', 'triple', 'multiple']
|
||||
*/
|
||||
filters.pluralize = function (value) {
|
||||
var args = slice.call(arguments, 1)
|
||||
return args.length > 1
|
||||
? (args[value - 1] || args[args.length - 1])
|
||||
: (args[value - 1] || args[0] + 's')
|
||||
}
|
||||
|
||||
/**
|
||||
* A special filter that takes a handler function,
|
||||
* wraps it so it only gets triggered on specific keypresses.
|
||||
*
|
||||
* v-on only
|
||||
*/
|
||||
|
||||
var keyCodes = {
|
||||
enter : 13,
|
||||
tab : 9,
|
||||
'delete' : 46,
|
||||
up : 38,
|
||||
left : 37,
|
||||
right : 39,
|
||||
down : 40,
|
||||
esc : 27
|
||||
}
|
||||
|
||||
filters.key = function (handler, key) {
|
||||
if (!handler) return
|
||||
var code = keyCodes[key]
|
||||
if (!code) {
|
||||
code = parseInt(key, 10)
|
||||
}
|
||||
return function (e) {
|
||||
if (e.keyCode === code) {
|
||||
return handler.call(this, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter filter for v-repeat
|
||||
*/
|
||||
filters.filterBy = function (arr, searchKey, delimiter, dataKey) {
|
||||
|
||||
// allow optional `in` delimiter
|
||||
// because why not
|
||||
if (delimiter && delimiter !== 'in') {
|
||||
dataKey = delimiter
|
||||
}
|
||||
|
||||
// get the search string
|
||||
var search = stripQuotes(searchKey) || this.$get(searchKey)
|
||||
if (!search) return arr
|
||||
search = search.toLowerCase()
|
||||
|
||||
// get the optional dataKey
|
||||
dataKey = dataKey && (stripQuotes(dataKey) || this.$get(dataKey))
|
||||
|
||||
// convert object to array
|
||||
if (!Array.isArray(arr)) {
|
||||
arr = utils.objectToArray(arr)
|
||||
}
|
||||
|
||||
return arr.filter(function (item) {
|
||||
return dataKey
|
||||
? contains(get(item, dataKey), search)
|
||||
: contains(item, search)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
filters.filterBy.computed = true
|
||||
|
||||
/**
|
||||
* Sort fitler for v-repeat
|
||||
*/
|
||||
filters.orderBy = function (arr, sortKey, reverseKey) {
|
||||
|
||||
var key = stripQuotes(sortKey) || this.$get(sortKey)
|
||||
if (!key) return arr
|
||||
|
||||
// convert object to array
|
||||
if (!Array.isArray(arr)) {
|
||||
arr = utils.objectToArray(arr)
|
||||
}
|
||||
|
||||
var order = 1
|
||||
if (reverseKey) {
|
||||
if (reverseKey === '-1') {
|
||||
order = -1
|
||||
} else if (reverseKey.charAt(0) === '!') {
|
||||
reverseKey = reverseKey.slice(1)
|
||||
order = this.$get(reverseKey) ? 1 : -1
|
||||
} else {
|
||||
order = this.$get(reverseKey) ? -1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
// sort on a copy to avoid mutating original array
|
||||
return arr.slice().sort(function (a, b) {
|
||||
a = get(a, key)
|
||||
b = get(b, key)
|
||||
return a === b ? 0 : a > b ? order : -order
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
filters.orderBy.computed = true
|
||||
|
||||
// Array filter helpers -------------------------------------------------------
|
||||
|
||||
/**
|
||||
* String contain helper
|
||||
*/
|
||||
function contains (val, search) {
|
||||
/* jshint eqeqeq: false */
|
||||
if (utils.isObject(val)) {
|
||||
for (var key in val) {
|
||||
if (contains(val[key], search)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else if (val != null) {
|
||||
return val.toString().toLowerCase().indexOf(search) > -1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether a string is in quotes,
|
||||
* if yes return stripped string
|
||||
*/
|
||||
function stripQuotes (str) {
|
||||
if (QUOTE_RE.test(str)) {
|
||||
return str.slice(1, -1)
|
||||
}
|
||||
}
|
84
vendor/assets/javascripts/bower/vue/src/fragment.js
vendored
Normal file
84
vendor/assets/javascripts/bower/vue/src/fragment.js
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
// string -> DOM conversion
|
||||
// wrappers originally from jQuery, scooped from component/domify
|
||||
var map = {
|
||||
legend : [1, '<fieldset>', '</fieldset>'],
|
||||
tr : [2, '<table><tbody>', '</tbody></table>'],
|
||||
col : [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
|
||||
_default : [0, '', '']
|
||||
}
|
||||
|
||||
map.td =
|
||||
map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>']
|
||||
|
||||
map.option =
|
||||
map.optgroup = [1, '<select multiple="multiple">', '</select>']
|
||||
|
||||
map.thead =
|
||||
map.tbody =
|
||||
map.colgroup =
|
||||
map.caption =
|
||||
map.tfoot = [1, '<table>', '</table>']
|
||||
|
||||
map.text =
|
||||
map.circle =
|
||||
map.ellipse =
|
||||
map.line =
|
||||
map.path =
|
||||
map.polygon =
|
||||
map.polyline =
|
||||
map.rect = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">','</svg>']
|
||||
|
||||
var TAG_RE = /<([\w:]+)/
|
||||
|
||||
module.exports = function (template) {
|
||||
|
||||
if (typeof template !== 'string') {
|
||||
return template
|
||||
}
|
||||
|
||||
// template by ID
|
||||
if (template.charAt(0) === '#') {
|
||||
var templateNode = document.getElementById(template.slice(1))
|
||||
if (!templateNode) return
|
||||
// if its a template tag and the browser supports it,
|
||||
// its content is already a document fragment!
|
||||
if (templateNode.tagName === 'TEMPLATE' && templateNode.content) {
|
||||
return templateNode.content
|
||||
}
|
||||
template = templateNode.innerHTML
|
||||
}
|
||||
|
||||
var frag = document.createDocumentFragment(),
|
||||
m = TAG_RE.exec(template)
|
||||
// text only
|
||||
if (!m) {
|
||||
frag.appendChild(document.createTextNode(template))
|
||||
return frag
|
||||
}
|
||||
|
||||
var tag = m[1],
|
||||
wrap = map[tag] || map._default,
|
||||
depth = wrap[0],
|
||||
prefix = wrap[1],
|
||||
suffix = wrap[2],
|
||||
node = document.createElement('div')
|
||||
|
||||
node.innerHTML = prefix + template.trim() + suffix
|
||||
while (depth--) node = node.lastChild
|
||||
|
||||
// one element
|
||||
if (node.firstChild === node.lastChild) {
|
||||
frag.appendChild(node.firstChild)
|
||||
return frag
|
||||
}
|
||||
|
||||
// multiple nodes, return a fragment
|
||||
var child
|
||||
/* jshint boss: true */
|
||||
while (child = node.firstChild) {
|
||||
if (node.nodeType === 1) {
|
||||
frag.appendChild(child)
|
||||
}
|
||||
}
|
||||
return frag
|
||||
}
|
186
vendor/assets/javascripts/bower/vue/src/main.js
vendored
Normal file
186
vendor/assets/javascripts/bower/vue/src/main.js
vendored
Normal file
@ -0,0 +1,186 @@
|
||||
var config = require('./config'),
|
||||
ViewModel = require('./viewmodel'),
|
||||
utils = require('./utils'),
|
||||
makeHash = utils.hash,
|
||||
assetTypes = ['directive', 'filter', 'partial', 'effect', 'component']
|
||||
|
||||
// require these so Browserify can catch them
|
||||
// so they can be used in Vue.require
|
||||
require('./observer')
|
||||
require('./transition')
|
||||
|
||||
ViewModel.options = config.globalAssets = {
|
||||
directives : require('./directives'),
|
||||
filters : require('./filters'),
|
||||
partials : makeHash(),
|
||||
effects : makeHash(),
|
||||
components : makeHash()
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose asset registration methods
|
||||
*/
|
||||
assetTypes.forEach(function (type) {
|
||||
ViewModel[type] = function (id, value) {
|
||||
var hash = this.options[type + 's']
|
||||
if (!hash) {
|
||||
hash = this.options[type + 's'] = makeHash()
|
||||
}
|
||||
if (!value) return hash[id]
|
||||
if (type === 'partial') {
|
||||
value = utils.toFragment(value)
|
||||
} else if (type === 'component') {
|
||||
value = utils.toConstructor(value)
|
||||
} else if (type === 'filter') {
|
||||
utils.checkFilter(value)
|
||||
}
|
||||
hash[id] = value
|
||||
return this
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Set config options
|
||||
*/
|
||||
ViewModel.config = function (opts, val) {
|
||||
if (typeof opts === 'string') {
|
||||
if (val === undefined) {
|
||||
return config[opts]
|
||||
} else {
|
||||
config[opts] = val
|
||||
}
|
||||
} else {
|
||||
utils.extend(config, opts)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose an interface for plugins
|
||||
*/
|
||||
ViewModel.use = function (plugin) {
|
||||
if (typeof plugin === 'string') {
|
||||
try {
|
||||
plugin = require(plugin)
|
||||
} catch (e) {
|
||||
utils.warn('Cannot find plugin: ' + plugin)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// additional parameters
|
||||
var args = [].slice.call(arguments, 1)
|
||||
args.unshift(this)
|
||||
|
||||
if (typeof plugin.install === 'function') {
|
||||
plugin.install.apply(plugin, args)
|
||||
} else {
|
||||
plugin.apply(null, args)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose internal modules for plugins
|
||||
*/
|
||||
ViewModel.require = function (path) {
|
||||
return require('./' + path)
|
||||
}
|
||||
|
||||
ViewModel.extend = extend
|
||||
ViewModel.nextTick = utils.nextTick
|
||||
|
||||
/**
|
||||
* Expose the main ViewModel class
|
||||
* and add extend method
|
||||
*/
|
||||
function extend (options) {
|
||||
|
||||
var ParentVM = this
|
||||
|
||||
// extend data options need to be copied
|
||||
// on instantiation
|
||||
if (options.data) {
|
||||
options.defaultData = options.data
|
||||
delete options.data
|
||||
}
|
||||
|
||||
// inherit options
|
||||
// but only when the super class is not the native Vue.
|
||||
if (ParentVM !== ViewModel) {
|
||||
options = inheritOptions(options, ParentVM.options, true)
|
||||
}
|
||||
utils.processOptions(options)
|
||||
|
||||
var ExtendedVM = function (opts, asParent) {
|
||||
if (!asParent) {
|
||||
opts = inheritOptions(opts, options, true)
|
||||
}
|
||||
ParentVM.call(this, opts, true)
|
||||
}
|
||||
|
||||
// inherit prototype props
|
||||
var proto = ExtendedVM.prototype = Object.create(ParentVM.prototype)
|
||||
utils.defProtected(proto, 'constructor', ExtendedVM)
|
||||
|
||||
// allow extended VM to be further extended
|
||||
ExtendedVM.extend = extend
|
||||
ExtendedVM.super = ParentVM
|
||||
ExtendedVM.options = options
|
||||
|
||||
// allow extended VM to add its own assets
|
||||
assetTypes.forEach(function (type) {
|
||||
ExtendedVM[type] = ViewModel[type]
|
||||
})
|
||||
|
||||
// allow extended VM to use plugins
|
||||
ExtendedVM.use = ViewModel.use
|
||||
ExtendedVM.require = ViewModel.require
|
||||
|
||||
return ExtendedVM
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherit options
|
||||
*
|
||||
* For options such as `data`, `vms`, `directives`, 'partials',
|
||||
* they should be further extended. However extending should only
|
||||
* be done at top level.
|
||||
*
|
||||
* `proto` is an exception because it's handled directly on the
|
||||
* prototype.
|
||||
*
|
||||
* `el` is an exception because it's not allowed as an
|
||||
* extension option, but only as an instance option.
|
||||
*/
|
||||
function inheritOptions (child, parent, topLevel) {
|
||||
child = child || {}
|
||||
if (!parent) return child
|
||||
for (var key in parent) {
|
||||
if (key === 'el') continue
|
||||
var val = child[key],
|
||||
parentVal = parent[key]
|
||||
if (topLevel && typeof val === 'function' && parentVal) {
|
||||
// merge hook functions into an array
|
||||
child[key] = [val]
|
||||
if (Array.isArray(parentVal)) {
|
||||
child[key] = child[key].concat(parentVal)
|
||||
} else {
|
||||
child[key].push(parentVal)
|
||||
}
|
||||
} else if (
|
||||
topLevel &&
|
||||
(utils.isTrueObject(val) || utils.isTrueObject(parentVal))
|
||||
&& !(parentVal instanceof ViewModel)
|
||||
) {
|
||||
// merge toplevel object options
|
||||
child[key] = inheritOptions(val, parentVal)
|
||||
} else if (val === undefined) {
|
||||
// inherit if child doesn't override
|
||||
child[key] = parentVal
|
||||
}
|
||||
}
|
||||
return child
|
||||
}
|
||||
|
||||
module.exports = ViewModel
|
446
vendor/assets/javascripts/bower/vue/src/observer.js
vendored
Normal file
446
vendor/assets/javascripts/bower/vue/src/observer.js
vendored
Normal file
@ -0,0 +1,446 @@
|
||||
/* jshint proto:true */
|
||||
|
||||
var Emitter = require('./emitter'),
|
||||
utils = require('./utils'),
|
||||
// cache methods
|
||||
def = utils.defProtected,
|
||||
isObject = utils.isObject,
|
||||
isArray = Array.isArray,
|
||||
hasOwn = ({}).hasOwnProperty,
|
||||
oDef = Object.defineProperty,
|
||||
slice = [].slice,
|
||||
// fix for IE + __proto__ problem
|
||||
// define methods as inenumerable if __proto__ is present,
|
||||
// otherwise enumerable so we can loop through and manually
|
||||
// attach to array instances
|
||||
hasProto = ({}).__proto__
|
||||
|
||||
// Array Mutation Handlers & Augmentations ------------------------------------
|
||||
|
||||
// The proxy prototype to replace the __proto__ of
|
||||
// an observed array
|
||||
var ArrayProxy = Object.create(Array.prototype)
|
||||
|
||||
// intercept mutation methods
|
||||
;[
|
||||
'push',
|
||||
'pop',
|
||||
'shift',
|
||||
'unshift',
|
||||
'splice',
|
||||
'sort',
|
||||
'reverse'
|
||||
].forEach(watchMutation)
|
||||
|
||||
// Augment the ArrayProxy with convenience methods
|
||||
def(ArrayProxy, '$set', function (index, data) {
|
||||
return this.splice(index, 1, data)[0]
|
||||
}, !hasProto)
|
||||
|
||||
def(ArrayProxy, '$remove', function (index) {
|
||||
if (typeof index !== 'number') {
|
||||
index = this.indexOf(index)
|
||||
}
|
||||
if (index > -1) {
|
||||
return this.splice(index, 1)[0]
|
||||
}
|
||||
}, !hasProto)
|
||||
|
||||
/**
|
||||
* Intercep a mutation event so we can emit the mutation info.
|
||||
* we also analyze what elements are added/removed and link/unlink
|
||||
* them with the parent Array.
|
||||
*/
|
||||
function watchMutation (method) {
|
||||
def(ArrayProxy, method, function () {
|
||||
|
||||
var args = slice.call(arguments),
|
||||
result = Array.prototype[method].apply(this, args),
|
||||
inserted, removed
|
||||
|
||||
// determine new / removed elements
|
||||
if (method === 'push' || method === 'unshift') {
|
||||
inserted = args
|
||||
} else if (method === 'pop' || method === 'shift') {
|
||||
removed = [result]
|
||||
} else if (method === 'splice') {
|
||||
inserted = args.slice(2)
|
||||
removed = result
|
||||
}
|
||||
|
||||
// link & unlink
|
||||
linkArrayElements(this, inserted)
|
||||
unlinkArrayElements(this, removed)
|
||||
|
||||
// emit the mutation event
|
||||
this.__emitter__.emit('mutate', '', this, {
|
||||
method : method,
|
||||
args : args,
|
||||
result : result,
|
||||
inserted : inserted,
|
||||
removed : removed
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
}, !hasProto)
|
||||
}
|
||||
|
||||
/**
|
||||
* Link new elements to an Array, so when they change
|
||||
* and emit events, the owner Array can be notified.
|
||||
*/
|
||||
function linkArrayElements (arr, items) {
|
||||
if (items) {
|
||||
var i = items.length, item, owners
|
||||
while (i--) {
|
||||
item = items[i]
|
||||
if (isWatchable(item)) {
|
||||
// if object is not converted for observing
|
||||
// convert it...
|
||||
if (!item.__emitter__) {
|
||||
convert(item)
|
||||
watch(item)
|
||||
}
|
||||
owners = item.__emitter__.owners
|
||||
if (owners.indexOf(arr) < 0) {
|
||||
owners.push(arr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink removed elements from the ex-owner Array.
|
||||
*/
|
||||
function unlinkArrayElements (arr, items) {
|
||||
if (items) {
|
||||
var i = items.length, item
|
||||
while (i--) {
|
||||
item = items[i]
|
||||
if (item && item.__emitter__) {
|
||||
var owners = item.__emitter__.owners
|
||||
if (owners) owners.splice(owners.indexOf(arr))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Object add/delete key augmentation -----------------------------------------
|
||||
|
||||
var ObjProxy = Object.create(Object.prototype)
|
||||
|
||||
def(ObjProxy, '$add', function (key, val) {
|
||||
if (hasOwn.call(this, key)) return
|
||||
this[key] = val
|
||||
convertKey(this, key, true)
|
||||
}, !hasProto)
|
||||
|
||||
def(ObjProxy, '$delete', function (key) {
|
||||
if (!(hasOwn.call(this, key))) return
|
||||
// trigger set events
|
||||
this[key] = undefined
|
||||
delete this[key]
|
||||
this.__emitter__.emit('delete', key)
|
||||
}, !hasProto)
|
||||
|
||||
// Watch Helpers --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Check if a value is watchable
|
||||
*/
|
||||
function isWatchable (obj) {
|
||||
return typeof obj === 'object' && obj && !obj.$compiler
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an Object/Array to give it a change emitter.
|
||||
*/
|
||||
function convert (obj) {
|
||||
if (obj.__emitter__) return true
|
||||
var emitter = new Emitter()
|
||||
def(obj, '__emitter__', emitter)
|
||||
emitter
|
||||
.on('set', function (key, val, propagate) {
|
||||
if (propagate) propagateChange(obj)
|
||||
})
|
||||
.on('mutate', function () {
|
||||
propagateChange(obj)
|
||||
})
|
||||
emitter.values = utils.hash()
|
||||
emitter.owners = []
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagate an array element's change to its owner arrays
|
||||
*/
|
||||
function propagateChange (obj) {
|
||||
var owners = obj.__emitter__.owners,
|
||||
i = owners.length
|
||||
while (i--) {
|
||||
owners[i].__emitter__.emit('set', '', '', true)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch target based on its type
|
||||
*/
|
||||
function watch (obj) {
|
||||
if (isArray(obj)) {
|
||||
watchArray(obj)
|
||||
} else {
|
||||
watchObject(obj)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Augment target objects with modified
|
||||
* methods
|
||||
*/
|
||||
function augment (target, src) {
|
||||
if (hasProto) {
|
||||
target.__proto__ = src
|
||||
} else {
|
||||
for (var key in src) {
|
||||
def(target, key, src[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch an Object, recursive.
|
||||
*/
|
||||
function watchObject (obj) {
|
||||
augment(obj, ObjProxy)
|
||||
for (var key in obj) {
|
||||
convertKey(obj, key)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch an Array, overload mutation methods
|
||||
* and add augmentations by intercepting the prototype chain
|
||||
*/
|
||||
function watchArray (arr) {
|
||||
augment(arr, ArrayProxy)
|
||||
linkArrayElements(arr, arr)
|
||||
}
|
||||
|
||||
/**
|
||||
* Define accessors for a property on an Object
|
||||
* so it emits get/set events.
|
||||
* Then watch the value itself.
|
||||
*/
|
||||
function convertKey (obj, key, propagate) {
|
||||
var keyPrefix = key.charAt(0)
|
||||
if (keyPrefix === '$' || keyPrefix === '_') {
|
||||
return
|
||||
}
|
||||
// emit set on bind
|
||||
// this means when an object is observed it will emit
|
||||
// a first batch of set events.
|
||||
var emitter = obj.__emitter__,
|
||||
values = emitter.values
|
||||
|
||||
init(obj[key], propagate)
|
||||
|
||||
oDef(obj, key, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: function () {
|
||||
var value = values[key]
|
||||
// only emit get on tip values
|
||||
if (pub.shouldGet) {
|
||||
emitter.emit('get', key)
|
||||
}
|
||||
return value
|
||||
},
|
||||
set: function (newVal) {
|
||||
var oldVal = values[key]
|
||||
unobserve(oldVal, key, emitter)
|
||||
copyPaths(newVal, oldVal)
|
||||
// an immediate property should notify its parent
|
||||
// to emit set for itself too
|
||||
init(newVal, true)
|
||||
}
|
||||
})
|
||||
|
||||
function init (val, propagate) {
|
||||
values[key] = val
|
||||
emitter.emit('set', key, val, propagate)
|
||||
if (isArray(val)) {
|
||||
emitter.emit('set', key + '.length', val.length, propagate)
|
||||
}
|
||||
observe(val, key, emitter)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When a value that is already converted is
|
||||
* observed again by another observer, we can skip
|
||||
* the watch conversion and simply emit set event for
|
||||
* all of its properties.
|
||||
*/
|
||||
function emitSet (obj) {
|
||||
var emitter = obj && obj.__emitter__
|
||||
if (!emitter) return
|
||||
if (isArray(obj)) {
|
||||
emitter.emit('set', 'length', obj.length)
|
||||
} else {
|
||||
var key, val
|
||||
for (key in obj) {
|
||||
val = obj[key]
|
||||
emitter.emit('set', key, val)
|
||||
emitSet(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure all the paths in an old object exists
|
||||
* in a new object.
|
||||
* So when an object changes, all missing keys will
|
||||
* emit a set event with undefined value.
|
||||
*/
|
||||
function copyPaths (newObj, oldObj) {
|
||||
if (!isObject(newObj) || !isObject(oldObj)) {
|
||||
return
|
||||
}
|
||||
var path, oldVal, newVal
|
||||
for (path in oldObj) {
|
||||
if (!(hasOwn.call(newObj, path))) {
|
||||
oldVal = oldObj[path]
|
||||
if (isArray(oldVal)) {
|
||||
newObj[path] = []
|
||||
} else if (isObject(oldVal)) {
|
||||
newVal = newObj[path] = {}
|
||||
copyPaths(newVal, oldVal)
|
||||
} else {
|
||||
newObj[path] = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* walk along a path and make sure it can be accessed
|
||||
* and enumerated in that object
|
||||
*/
|
||||
function ensurePath (obj, key) {
|
||||
var path = key.split('.'), sec
|
||||
for (var i = 0, d = path.length - 1; i < d; i++) {
|
||||
sec = path[i]
|
||||
if (!obj[sec]) {
|
||||
obj[sec] = {}
|
||||
if (obj.__emitter__) convertKey(obj, sec)
|
||||
}
|
||||
obj = obj[sec]
|
||||
}
|
||||
if (isObject(obj)) {
|
||||
sec = path[i]
|
||||
if (!(hasOwn.call(obj, sec))) {
|
||||
obj[sec] = undefined
|
||||
if (obj.__emitter__) convertKey(obj, sec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main API Methods -----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Observe an object with a given path,
|
||||
* and proxy get/set/mutate events to the provided observer.
|
||||
*/
|
||||
function observe (obj, rawPath, observer) {
|
||||
|
||||
if (!isWatchable(obj)) return
|
||||
|
||||
var path = rawPath ? rawPath + '.' : '',
|
||||
alreadyConverted = convert(obj),
|
||||
emitter = obj.__emitter__
|
||||
|
||||
// setup proxy listeners on the parent observer.
|
||||
// we need to keep reference to them so that they
|
||||
// can be removed when the object is un-observed.
|
||||
observer.proxies = observer.proxies || {}
|
||||
var proxies = observer.proxies[path] = {
|
||||
get: function (key) {
|
||||
observer.emit('get', path + key)
|
||||
},
|
||||
set: function (key, val, propagate) {
|
||||
if (key) observer.emit('set', path + key, val)
|
||||
// also notify observer that the object itself changed
|
||||
// but only do so when it's a immediate property. this
|
||||
// avoids duplicate event firing.
|
||||
if (rawPath && propagate) {
|
||||
observer.emit('set', rawPath, obj, true)
|
||||
}
|
||||
},
|
||||
mutate: function (key, val, mutation) {
|
||||
// if the Array is a root value
|
||||
// the key will be null
|
||||
var fixedPath = key ? path + key : rawPath
|
||||
observer.emit('mutate', fixedPath, val, mutation)
|
||||
// also emit set for Array's length when it mutates
|
||||
var m = mutation.method
|
||||
if (m !== 'sort' && m !== 'reverse') {
|
||||
observer.emit('set', fixedPath + '.length', val.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// attach the listeners to the child observer.
|
||||
// now all the events will propagate upwards.
|
||||
emitter
|
||||
.on('get', proxies.get)
|
||||
.on('set', proxies.set)
|
||||
.on('mutate', proxies.mutate)
|
||||
|
||||
if (alreadyConverted) {
|
||||
// for objects that have already been converted,
|
||||
// emit set events for everything inside
|
||||
emitSet(obj)
|
||||
} else {
|
||||
watch(obj)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel observation, turn off the listeners.
|
||||
*/
|
||||
function unobserve (obj, path, observer) {
|
||||
|
||||
if (!obj || !obj.__emitter__) return
|
||||
|
||||
path = path ? path + '.' : ''
|
||||
var proxies = observer.proxies[path]
|
||||
if (!proxies) return
|
||||
|
||||
// turn off listeners
|
||||
obj.__emitter__
|
||||
.off('get', proxies.get)
|
||||
.off('set', proxies.set)
|
||||
.off('mutate', proxies.mutate)
|
||||
|
||||
// remove reference
|
||||
observer.proxies[path] = null
|
||||
}
|
||||
|
||||
// Expose API -----------------------------------------------------------------
|
||||
|
||||
var pub = module.exports = {
|
||||
|
||||
// whether to emit get events
|
||||
// only enabled during dependency parsing
|
||||
shouldGet : false,
|
||||
|
||||
observe : observe,
|
||||
unobserve : unobserve,
|
||||
ensurePath : ensurePath,
|
||||
copyPaths : copyPaths,
|
||||
watch : watch,
|
||||
convert : convert,
|
||||
convertKey : convertKey
|
||||
}
|
95
vendor/assets/javascripts/bower/vue/src/text-parser.js
vendored
Normal file
95
vendor/assets/javascripts/bower/vue/src/text-parser.js
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
var openChar = '{',
|
||||
endChar = '}',
|
||||
ESCAPE_RE = /[-.*+?^${}()|[\]\/\\]/g,
|
||||
BINDING_RE = buildInterpolationRegex(),
|
||||
// lazy require
|
||||
Directive
|
||||
|
||||
function buildInterpolationRegex () {
|
||||
var open = escapeRegex(openChar),
|
||||
end = escapeRegex(endChar)
|
||||
return new RegExp(open + open + open + '?(.+?)' + end + '?' + end + end)
|
||||
}
|
||||
|
||||
function escapeRegex (str) {
|
||||
return str.replace(ESCAPE_RE, '\\$&')
|
||||
}
|
||||
|
||||
function setDelimiters (delimiters) {
|
||||
exports.delimiters = delimiters
|
||||
openChar = delimiters[0]
|
||||
endChar = delimiters[1]
|
||||
BINDING_RE = buildInterpolationRegex()
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a piece of text, return an array of tokens
|
||||
* token types:
|
||||
* 1. plain string
|
||||
* 2. object with key = binding key
|
||||
* 3. object with key & html = true
|
||||
*/
|
||||
function parse (text) {
|
||||
if (!BINDING_RE.test(text)) return null
|
||||
var m, i, token, match, tokens = []
|
||||
/* jshint boss: true */
|
||||
while (m = text.match(BINDING_RE)) {
|
||||
i = m.index
|
||||
if (i > 0) tokens.push(text.slice(0, i))
|
||||
token = { key: m[1].trim() }
|
||||
match = m[0]
|
||||
token.html =
|
||||
match.charAt(2) === openChar &&
|
||||
match.charAt(match.length - 3) === endChar
|
||||
tokens.push(token)
|
||||
text = text.slice(i + m[0].length)
|
||||
}
|
||||
if (text.length) tokens.push(text)
|
||||
return tokens
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an attribute value with possible interpolation tags
|
||||
* return a Directive-friendly expression
|
||||
*
|
||||
* e.g. a {{b}} c => "a " + b + " c"
|
||||
*/
|
||||
function parseAttr (attr) {
|
||||
Directive = Directive || require('./directive')
|
||||
var tokens = parse(attr)
|
||||
if (!tokens) return null
|
||||
if (tokens.length === 1) return tokens[0].key
|
||||
var res = [], token
|
||||
for (var i = 0, l = tokens.length; i < l; i++) {
|
||||
token = tokens[i]
|
||||
res.push(
|
||||
token.key
|
||||
? inlineFilters(token.key)
|
||||
: ('"' + token + '"')
|
||||
)
|
||||
}
|
||||
return res.join('+')
|
||||
}
|
||||
|
||||
/**
|
||||
* Inlines any possible filters in a binding
|
||||
* so that we can combine everything into a huge expression
|
||||
*/
|
||||
function inlineFilters (key) {
|
||||
if (key.indexOf('|') > -1) {
|
||||
var dirs = Directive.parse(key),
|
||||
dir = dirs && dirs[0]
|
||||
if (dir && dir.filters) {
|
||||
key = Directive.inlineFilters(
|
||||
dir.key,
|
||||
dir.filters
|
||||
)
|
||||
}
|
||||
}
|
||||
return '(' + key + ')'
|
||||
}
|
||||
|
||||
exports.parse = parse
|
||||
exports.parseAttr = parseAttr
|
||||
exports.setDelimiters = setDelimiters
|
||||
exports.delimiters = [openChar, endChar]
|
226
vendor/assets/javascripts/bower/vue/src/transition.js
vendored
Normal file
226
vendor/assets/javascripts/bower/vue/src/transition.js
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
var endEvents = sniffEndEvents(),
|
||||
config = require('./config'),
|
||||
// batch enter animations so we only force the layout once
|
||||
Batcher = require('./batcher'),
|
||||
batcher = new Batcher(),
|
||||
// cache timer functions
|
||||
setTO = window.setTimeout,
|
||||
clearTO = window.clearTimeout,
|
||||
// exit codes for testing
|
||||
codes = {
|
||||
CSS_E : 1,
|
||||
CSS_L : 2,
|
||||
JS_E : 3,
|
||||
JS_L : 4,
|
||||
CSS_SKIP : -1,
|
||||
JS_SKIP : -2,
|
||||
JS_SKIP_E : -3,
|
||||
JS_SKIP_L : -4,
|
||||
INIT : -5,
|
||||
SKIP : -6
|
||||
}
|
||||
|
||||
// force layout before triggering transitions/animations
|
||||
batcher._preFlush = function () {
|
||||
/* jshint unused: false */
|
||||
var f = document.body.offsetHeight
|
||||
}
|
||||
|
||||
/**
|
||||
* stage:
|
||||
* 1 = enter
|
||||
* 2 = leave
|
||||
*/
|
||||
var transition = module.exports = function (el, stage, cb, compiler) {
|
||||
|
||||
var changeState = function () {
|
||||
cb()
|
||||
compiler.execHook(stage > 0 ? 'attached' : 'detached')
|
||||
}
|
||||
|
||||
if (compiler.init) {
|
||||
changeState()
|
||||
return codes.INIT
|
||||
}
|
||||
|
||||
var hasTransition = el.vue_trans === '',
|
||||
hasAnimation = el.vue_anim === '',
|
||||
effectId = el.vue_effect
|
||||
|
||||
if (effectId) {
|
||||
return applyTransitionFunctions(
|
||||
el,
|
||||
stage,
|
||||
changeState,
|
||||
effectId,
|
||||
compiler
|
||||
)
|
||||
} else if (hasTransition || hasAnimation) {
|
||||
return applyTransitionClass(
|
||||
el,
|
||||
stage,
|
||||
changeState,
|
||||
hasAnimation
|
||||
)
|
||||
} else {
|
||||
changeState()
|
||||
return codes.SKIP
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
transition.codes = codes
|
||||
|
||||
/**
|
||||
* Togggle a CSS class to trigger transition
|
||||
*/
|
||||
function applyTransitionClass (el, stage, changeState, hasAnimation) {
|
||||
|
||||
if (!endEvents.trans) {
|
||||
changeState()
|
||||
return codes.CSS_SKIP
|
||||
}
|
||||
|
||||
// if the browser supports transition,
|
||||
// it must have classList...
|
||||
var onEnd,
|
||||
classList = el.classList,
|
||||
existingCallback = el.vue_trans_cb,
|
||||
enterClass = config.enterClass,
|
||||
leaveClass = config.leaveClass,
|
||||
endEvent = hasAnimation ? endEvents.anim : endEvents.trans
|
||||
|
||||
// cancel unfinished callbacks and jobs
|
||||
if (existingCallback) {
|
||||
el.removeEventListener(endEvent, existingCallback)
|
||||
classList.remove(enterClass)
|
||||
classList.remove(leaveClass)
|
||||
el.vue_trans_cb = null
|
||||
}
|
||||
|
||||
if (stage > 0) { // enter
|
||||
|
||||
// set to enter state before appending
|
||||
classList.add(enterClass)
|
||||
// append
|
||||
changeState()
|
||||
// trigger transition
|
||||
if (!hasAnimation) {
|
||||
batcher.push({
|
||||
execute: function () {
|
||||
classList.remove(enterClass)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
onEnd = function (e) {
|
||||
if (e.target === el) {
|
||||
el.removeEventListener(endEvent, onEnd)
|
||||
el.vue_trans_cb = null
|
||||
classList.remove(enterClass)
|
||||
}
|
||||
}
|
||||
el.addEventListener(endEvent, onEnd)
|
||||
el.vue_trans_cb = onEnd
|
||||
}
|
||||
return codes.CSS_E
|
||||
|
||||
} else { // leave
|
||||
|
||||
if (el.offsetWidth || el.offsetHeight) {
|
||||
// trigger hide transition
|
||||
classList.add(leaveClass)
|
||||
onEnd = function (e) {
|
||||
if (e.target === el) {
|
||||
el.removeEventListener(endEvent, onEnd)
|
||||
el.vue_trans_cb = null
|
||||
// actually remove node here
|
||||
changeState()
|
||||
classList.remove(leaveClass)
|
||||
}
|
||||
}
|
||||
// attach transition end listener
|
||||
el.addEventListener(endEvent, onEnd)
|
||||
el.vue_trans_cb = onEnd
|
||||
} else {
|
||||
// directly remove invisible elements
|
||||
changeState()
|
||||
}
|
||||
return codes.CSS_L
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function applyTransitionFunctions (el, stage, changeState, effectId, compiler) {
|
||||
|
||||
var funcs = compiler.getOption('effects', effectId)
|
||||
if (!funcs) {
|
||||
changeState()
|
||||
return codes.JS_SKIP
|
||||
}
|
||||
|
||||
var enter = funcs.enter,
|
||||
leave = funcs.leave,
|
||||
timeouts = el.vue_timeouts
|
||||
|
||||
// clear previous timeouts
|
||||
if (timeouts) {
|
||||
var i = timeouts.length
|
||||
while (i--) {
|
||||
clearTO(timeouts[i])
|
||||
}
|
||||
}
|
||||
|
||||
timeouts = el.vue_timeouts = []
|
||||
function timeout (cb, delay) {
|
||||
var id = setTO(function () {
|
||||
cb()
|
||||
timeouts.splice(timeouts.indexOf(id), 1)
|
||||
if (!timeouts.length) {
|
||||
el.vue_timeouts = null
|
||||
}
|
||||
}, delay)
|
||||
timeouts.push(id)
|
||||
}
|
||||
|
||||
if (stage > 0) { // enter
|
||||
if (typeof enter !== 'function') {
|
||||
changeState()
|
||||
return codes.JS_SKIP_E
|
||||
}
|
||||
enter(el, changeState, timeout)
|
||||
return codes.JS_E
|
||||
} else { // leave
|
||||
if (typeof leave !== 'function') {
|
||||
changeState()
|
||||
return codes.JS_SKIP_L
|
||||
}
|
||||
leave(el, changeState, timeout)
|
||||
return codes.JS_L
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sniff proper transition end event name
|
||||
*/
|
||||
function sniffEndEvents () {
|
||||
var el = document.createElement('vue'),
|
||||
defaultEvent = 'transitionend',
|
||||
events = {
|
||||
'transition' : defaultEvent,
|
||||
'mozTransition' : defaultEvent,
|
||||
'webkitTransition' : 'webkitTransitionEnd'
|
||||
},
|
||||
ret = {}
|
||||
for (var name in events) {
|
||||
if (el.style[name] !== undefined) {
|
||||
ret.trans = events[name]
|
||||
break
|
||||
}
|
||||
}
|
||||
ret.anim = el.style.animation === ''
|
||||
? 'animationend'
|
||||
: 'webkitAnimationEnd'
|
||||
return ret
|
||||
}
|
307
vendor/assets/javascripts/bower/vue/src/utils.js
vendored
Normal file
307
vendor/assets/javascripts/bower/vue/src/utils.js
vendored
Normal file
@ -0,0 +1,307 @@
|
||||
var config = require('./config'),
|
||||
toString = ({}).toString,
|
||||
win = window,
|
||||
console = win.console,
|
||||
def = Object.defineProperty,
|
||||
OBJECT = 'object',
|
||||
THIS_RE = /[^\w]this[^\w]/,
|
||||
hasClassList = 'classList' in document.documentElement,
|
||||
ViewModel // late def
|
||||
|
||||
var defer =
|
||||
win.requestAnimationFrame ||
|
||||
win.webkitRequestAnimationFrame ||
|
||||
win.setTimeout
|
||||
|
||||
var utils = module.exports = {
|
||||
|
||||
/**
|
||||
* Convert a string template to a dom fragment
|
||||
*/
|
||||
toFragment: require('./fragment'),
|
||||
|
||||
/**
|
||||
* get a value from an object keypath
|
||||
*/
|
||||
get: function (obj, key) {
|
||||
/* jshint eqeqeq: false */
|
||||
if (key.indexOf('.') < 0) {
|
||||
return obj[key]
|
||||
}
|
||||
var path = key.split('.'),
|
||||
d = -1, l = path.length
|
||||
while (++d < l && obj != null) {
|
||||
obj = obj[path[d]]
|
||||
}
|
||||
return obj
|
||||
},
|
||||
|
||||
/**
|
||||
* set a value to an object keypath
|
||||
*/
|
||||
set: function (obj, key, val) {
|
||||
/* jshint eqeqeq: false */
|
||||
if (key.indexOf('.') < 0) {
|
||||
obj[key] = val
|
||||
return
|
||||
}
|
||||
var path = key.split('.'),
|
||||
d = -1, l = path.length - 1
|
||||
while (++d < l) {
|
||||
if (obj[path[d]] == null) {
|
||||
obj[path[d]] = {}
|
||||
}
|
||||
obj = obj[path[d]]
|
||||
}
|
||||
obj[path[d]] = val
|
||||
},
|
||||
|
||||
/**
|
||||
* return the base segment of a keypath
|
||||
*/
|
||||
baseKey: function (key) {
|
||||
return key.indexOf('.') > 0
|
||||
? key.split('.')[0]
|
||||
: key
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a prototype-less object
|
||||
* which is a better hash/map
|
||||
*/
|
||||
hash: function () {
|
||||
return Object.create(null)
|
||||
},
|
||||
|
||||
/**
|
||||
* get an attribute and remove it.
|
||||
*/
|
||||
attr: function (el, type) {
|
||||
var attr = config.prefix + '-' + type,
|
||||
val = el.getAttribute(attr)
|
||||
if (val !== null) {
|
||||
el.removeAttribute(attr)
|
||||
}
|
||||
return val
|
||||
},
|
||||
|
||||
/**
|
||||
* Define an ienumerable property
|
||||
* This avoids it being included in JSON.stringify
|
||||
* or for...in loops.
|
||||
*/
|
||||
defProtected: function (obj, key, val, enumerable, writable) {
|
||||
def(obj, key, {
|
||||
value : val,
|
||||
enumerable : enumerable,
|
||||
writable : writable,
|
||||
configurable : true
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* A less bullet-proof but more efficient type check
|
||||
* than Object.prototype.toString
|
||||
*/
|
||||
isObject: function (obj) {
|
||||
return typeof obj === OBJECT && obj && !Array.isArray(obj)
|
||||
},
|
||||
|
||||
/**
|
||||
* A more accurate but less efficient type check
|
||||
*/
|
||||
isTrueObject: function (obj) {
|
||||
return toString.call(obj) === '[object Object]'
|
||||
},
|
||||
|
||||
/**
|
||||
* Most simple bind
|
||||
* enough for the usecase and fast than native bind()
|
||||
*/
|
||||
bind: function (fn, ctx) {
|
||||
return function (arg) {
|
||||
return fn.call(ctx, arg)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Make sure null and undefined output empty string
|
||||
*/
|
||||
guard: function (value) {
|
||||
/* jshint eqeqeq: false, eqnull: true */
|
||||
return value == null
|
||||
? ''
|
||||
: (typeof value == 'object')
|
||||
? JSON.stringify(value)
|
||||
: value
|
||||
},
|
||||
|
||||
/**
|
||||
* When setting value on the VM, parse possible numbers
|
||||
*/
|
||||
checkNumber: function (value) {
|
||||
return (isNaN(value) || value === null || typeof value === 'boolean')
|
||||
? value
|
||||
: Number(value)
|
||||
},
|
||||
|
||||
/**
|
||||
* simple extend
|
||||
*/
|
||||
extend: function (obj, ext) {
|
||||
for (var key in ext) {
|
||||
if (obj[key] !== ext[key]) {
|
||||
obj[key] = ext[key]
|
||||
}
|
||||
}
|
||||
return obj
|
||||
},
|
||||
|
||||
/**
|
||||
* filter an array with duplicates into uniques
|
||||
*/
|
||||
unique: function (arr) {
|
||||
var hash = utils.hash(),
|
||||
i = arr.length,
|
||||
key, res = []
|
||||
while (i--) {
|
||||
key = arr[i]
|
||||
if (hash[key]) continue
|
||||
hash[key] = 1
|
||||
res.push(key)
|
||||
}
|
||||
return res
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert the object to a ViewModel constructor
|
||||
* if it is not already one
|
||||
*/
|
||||
toConstructor: function (obj) {
|
||||
ViewModel = ViewModel || require('./viewmodel')
|
||||
return utils.isObject(obj)
|
||||
? ViewModel.extend(obj)
|
||||
: typeof obj === 'function'
|
||||
? obj
|
||||
: null
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if a filter function contains references to `this`
|
||||
* If yes, mark it as a computed filter.
|
||||
*/
|
||||
checkFilter: function (filter) {
|
||||
if (THIS_RE.test(filter.toString())) {
|
||||
filter.computed = true
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* convert certain option values to the desired format.
|
||||
*/
|
||||
processOptions: function (options) {
|
||||
var components = options.components,
|
||||
partials = options.partials,
|
||||
template = options.template,
|
||||
filters = options.filters,
|
||||
key
|
||||
if (components) {
|
||||
for (key in components) {
|
||||
components[key] = utils.toConstructor(components[key])
|
||||
}
|
||||
}
|
||||
if (partials) {
|
||||
for (key in partials) {
|
||||
partials[key] = utils.toFragment(partials[key])
|
||||
}
|
||||
}
|
||||
if (filters) {
|
||||
for (key in filters) {
|
||||
utils.checkFilter(filters[key])
|
||||
}
|
||||
}
|
||||
if (template) {
|
||||
options.template = utils.toFragment(template)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* used to defer batch updates
|
||||
*/
|
||||
nextTick: function (cb) {
|
||||
defer(cb, 0)
|
||||
},
|
||||
|
||||
/**
|
||||
* add class for IE9
|
||||
* uses classList if available
|
||||
*/
|
||||
addClass: function (el, cls) {
|
||||
if (hasClassList) {
|
||||
el.classList.add(cls)
|
||||
} else {
|
||||
var cur = ' ' + el.className + ' '
|
||||
if (cur.indexOf(' ' + cls + ' ') < 0) {
|
||||
el.className = (cur + cls).trim()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* remove class for IE9
|
||||
*/
|
||||
removeClass: function (el, cls) {
|
||||
if (hasClassList) {
|
||||
el.classList.remove(cls)
|
||||
} else {
|
||||
var cur = ' ' + el.className + ' ',
|
||||
tar = ' ' + cls + ' '
|
||||
while (cur.indexOf(tar) >= 0) {
|
||||
cur = cur.replace(tar, ' ')
|
||||
}
|
||||
el.className = cur.trim()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert an object to Array
|
||||
* used in v-repeat and array filters
|
||||
*/
|
||||
objectToArray: function (obj) {
|
||||
var res = [], val, data
|
||||
for (var key in obj) {
|
||||
val = obj[key]
|
||||
data = utils.isObject(val)
|
||||
? val
|
||||
: { $value: val }
|
||||
data.$key = key
|
||||
res.push(data)
|
||||
}
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
enableDebug()
|
||||
function enableDebug () {
|
||||
/**
|
||||
* log for debugging
|
||||
*/
|
||||
utils.log = function (msg) {
|
||||
if (config.debug && console) {
|
||||
console.log(msg)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* warnings, traces by default
|
||||
* can be suppressed by `silent` option.
|
||||
*/
|
||||
utils.warn = function (msg) {
|
||||
if (!config.silent && console) {
|
||||
console.warn(msg)
|
||||
if (config.debug && console.trace) {
|
||||
console.trace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
180
vendor/assets/javascripts/bower/vue/src/viewmodel.js
vendored
Normal file
180
vendor/assets/javascripts/bower/vue/src/viewmodel.js
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
var Compiler = require('./compiler'),
|
||||
utils = require('./utils'),
|
||||
transition = require('./transition'),
|
||||
Batcher = require('./batcher'),
|
||||
slice = [].slice,
|
||||
def = utils.defProtected,
|
||||
nextTick = utils.nextTick,
|
||||
|
||||
// batch $watch callbacks
|
||||
watcherBatcher = new Batcher(),
|
||||
watcherId = 1
|
||||
|
||||
/**
|
||||
* ViewModel exposed to the user that holds data,
|
||||
* computed properties, event handlers
|
||||
* and a few reserved methods
|
||||
*/
|
||||
function ViewModel (options) {
|
||||
// just compile. options are passed directly to compiler
|
||||
new Compiler(this, options)
|
||||
}
|
||||
|
||||
// All VM prototype methods are inenumerable
|
||||
// so it can be stringified/looped through as raw data
|
||||
var VMProto = ViewModel.prototype
|
||||
|
||||
/**
|
||||
* Convenience function to get a value from
|
||||
* a keypath
|
||||
*/
|
||||
def(VMProto, '$get', function (key) {
|
||||
var val = utils.get(this, key)
|
||||
return val === undefined && this.$parent
|
||||
? this.$parent.$get(key)
|
||||
: val
|
||||
})
|
||||
|
||||
/**
|
||||
* Convenience function to set an actual nested value
|
||||
* from a flat key string. Used in directives.
|
||||
*/
|
||||
def(VMProto, '$set', function (key, value) {
|
||||
utils.set(this, key, value)
|
||||
})
|
||||
|
||||
/**
|
||||
* watch a key on the viewmodel for changes
|
||||
* fire callback with new value
|
||||
*/
|
||||
def(VMProto, '$watch', function (key, callback) {
|
||||
// save a unique id for each watcher
|
||||
var id = watcherId++,
|
||||
self = this
|
||||
function on () {
|
||||
var args = slice.call(arguments)
|
||||
watcherBatcher.push({
|
||||
id: id,
|
||||
override: true,
|
||||
execute: function () {
|
||||
callback.apply(self, args)
|
||||
}
|
||||
})
|
||||
}
|
||||
callback._fn = on
|
||||
self.$compiler.observer.on('change:' + key, on)
|
||||
})
|
||||
|
||||
/**
|
||||
* unwatch a key
|
||||
*/
|
||||
def(VMProto, '$unwatch', function (key, callback) {
|
||||
// workaround here
|
||||
// since the emitter module checks callback existence
|
||||
// by checking the length of arguments
|
||||
var args = ['change:' + key],
|
||||
ob = this.$compiler.observer
|
||||
if (callback) args.push(callback._fn)
|
||||
ob.off.apply(ob, args)
|
||||
})
|
||||
|
||||
/**
|
||||
* unbind everything, remove everything
|
||||
*/
|
||||
def(VMProto, '$destroy', function () {
|
||||
this.$compiler.destroy()
|
||||
})
|
||||
|
||||
/**
|
||||
* broadcast an event to all child VMs recursively.
|
||||
*/
|
||||
def(VMProto, '$broadcast', function () {
|
||||
var children = this.$compiler.children,
|
||||
i = children.length,
|
||||
child
|
||||
while (i--) {
|
||||
child = children[i]
|
||||
child.emitter.applyEmit.apply(child.emitter, arguments)
|
||||
child.vm.$broadcast.apply(child.vm, arguments)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* emit an event that propagates all the way up to parent VMs.
|
||||
*/
|
||||
def(VMProto, '$dispatch', function () {
|
||||
var compiler = this.$compiler,
|
||||
emitter = compiler.emitter,
|
||||
parent = compiler.parent
|
||||
emitter.applyEmit.apply(emitter, arguments)
|
||||
if (parent) {
|
||||
parent.vm.$dispatch.apply(parent.vm, arguments)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* delegate on/off/once to the compiler's emitter
|
||||
*/
|
||||
;['emit', 'on', 'off', 'once'].forEach(function (method) {
|
||||
// internal emit has fixed number of arguments.
|
||||
// exposed emit uses the external version
|
||||
// with fn.apply.
|
||||
var realMethod = method === 'emit'
|
||||
? 'applyEmit'
|
||||
: method
|
||||
def(VMProto, '$' + method, function () {
|
||||
var emitter = this.$compiler.emitter
|
||||
emitter[realMethod].apply(emitter, arguments)
|
||||
})
|
||||
})
|
||||
|
||||
// DOM convenience methods
|
||||
|
||||
def(VMProto, '$appendTo', function (target, cb) {
|
||||
target = query(target)
|
||||
var el = this.$el
|
||||
transition(el, 1, function () {
|
||||
target.appendChild(el)
|
||||
if (cb) nextTick(cb)
|
||||
}, this.$compiler)
|
||||
})
|
||||
|
||||
def(VMProto, '$remove', function (cb) {
|
||||
var el = this.$el
|
||||
transition(el, -1, function () {
|
||||
if (el.parentNode) {
|
||||
el.parentNode.removeChild(el)
|
||||
}
|
||||
if (cb) nextTick(cb)
|
||||
}, this.$compiler)
|
||||
})
|
||||
|
||||
def(VMProto, '$before', function (target, cb) {
|
||||
target = query(target)
|
||||
var el = this.$el
|
||||
transition(el, 1, function () {
|
||||
target.parentNode.insertBefore(el, target)
|
||||
if (cb) nextTick(cb)
|
||||
}, this.$compiler)
|
||||
})
|
||||
|
||||
def(VMProto, '$after', function (target, cb) {
|
||||
target = query(target)
|
||||
var el = this.$el
|
||||
transition(el, 1, function () {
|
||||
if (target.nextSibling) {
|
||||
target.parentNode.insertBefore(el, target.nextSibling)
|
||||
} else {
|
||||
target.parentNode.appendChild(el)
|
||||
}
|
||||
if (cb) nextTick(cb)
|
||||
}, this.$compiler)
|
||||
})
|
||||
|
||||
function query (el) {
|
||||
return typeof el === 'string'
|
||||
? document.querySelector(el)
|
||||
: el
|
||||
}
|
||||
|
||||
module.exports = ViewModel
|
Loading…
Reference in New Issue
Block a user