mirror of
https://github.com/fluent/fluentd-ui.git
synced 2025-08-12 17:27:09 +02:00
7616 lines
168 KiB
JavaScript
7616 lines
168 KiB
JavaScript
/**
|
|
* Vue.js v0.11.0
|
|
* (c) 2014 Evan You
|
|
* Released under the MIT License.
|
|
*/
|
|
|
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
module.exports = factory();
|
|
else if(typeof define === 'function' && define.amd)
|
|
define(factory);
|
|
else if(typeof exports === 'object')
|
|
exports["Vue"] = factory();
|
|
else
|
|
root["Vue"] = factory();
|
|
})(this, function() {
|
|
return /******/ (function(modules) { // webpackBootstrap
|
|
/******/ // The module cache
|
|
/******/ var installedModules = {};
|
|
/******/
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
/******/
|
|
/******/ // Check if module is in cache
|
|
/******/ if(installedModules[moduleId])
|
|
/******/ return installedModules[moduleId].exports;
|
|
/******/
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ var module = installedModules[moduleId] = {
|
|
/******/ exports: {},
|
|
/******/ id: moduleId,
|
|
/******/ loaded: false
|
|
/******/ };
|
|
/******/
|
|
/******/ // Execute the module function
|
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
/******/
|
|
/******/ // Flag the module as loaded
|
|
/******/ module.loaded = true;
|
|
/******/
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.exports;
|
|
/******/ }
|
|
/******/
|
|
/******/
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
/******/ __webpack_require__.m = modules;
|
|
/******/
|
|
/******/ // expose the module cache
|
|
/******/ __webpack_require__.c = installedModules;
|
|
/******/
|
|
/******/ // __webpack_public_path__
|
|
/******/ __webpack_require__.p = "";
|
|
/******/
|
|
/******/ // Load entry module and return exports
|
|
/******/ return __webpack_require__(0);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var extend = _.extend
|
|
|
|
/**
|
|
* The exposed Vue constructor.
|
|
*
|
|
* API conventions:
|
|
* - public API methods/properties are prefiexed with `$`
|
|
* - internal methods/properties are prefixed with `_`
|
|
* - non-prefixed properties are assumed to be proxied user
|
|
* data.
|
|
*
|
|
* @constructor
|
|
* @param {Object} [options]
|
|
* @public
|
|
*/
|
|
|
|
function Vue (options) {
|
|
this._init(options)
|
|
}
|
|
|
|
/**
|
|
* Mixin global API
|
|
*/
|
|
|
|
extend(Vue, __webpack_require__(2))
|
|
|
|
/**
|
|
* Vue and every constructor that extends Vue has an
|
|
* associated options object, which can be accessed during
|
|
* compilation steps as `this.constructor.options`.
|
|
*
|
|
* These can be seen as the default options of every
|
|
* Vue instance.
|
|
*/
|
|
|
|
Vue.options = {
|
|
directives : __webpack_require__(8),
|
|
filters : __webpack_require__(9),
|
|
partials : {},
|
|
transitions : {},
|
|
components : {}
|
|
}
|
|
|
|
/**
|
|
* Build up the prototype
|
|
*/
|
|
|
|
var p = Vue.prototype
|
|
|
|
/**
|
|
* $data has a setter which does a bunch of
|
|
* teardown/setup work
|
|
*/
|
|
|
|
Object.defineProperty(p, '$data', {
|
|
get: function () {
|
|
return this._data
|
|
},
|
|
set: function (newData) {
|
|
this._setData(newData)
|
|
}
|
|
})
|
|
|
|
/**
|
|
* Mixin internal instance methods
|
|
*/
|
|
|
|
extend(p, __webpack_require__(10))
|
|
extend(p, __webpack_require__(11))
|
|
extend(p, __webpack_require__(12))
|
|
extend(p, __webpack_require__(13))
|
|
|
|
/**
|
|
* Mixin public API methods
|
|
*/
|
|
|
|
extend(p, __webpack_require__(3))
|
|
extend(p, __webpack_require__(4))
|
|
extend(p, __webpack_require__(5))
|
|
extend(p, __webpack_require__(6))
|
|
extend(p, __webpack_require__(7))
|
|
|
|
module.exports = _.Vue = Vue
|
|
|
|
/***/ },
|
|
/* 1 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var lang = __webpack_require__(14)
|
|
var extend = lang.extend
|
|
|
|
extend(exports, lang)
|
|
extend(exports, __webpack_require__(15))
|
|
extend(exports, __webpack_require__(16))
|
|
extend(exports, __webpack_require__(17))
|
|
extend(exports, __webpack_require__(18))
|
|
|
|
/***/ },
|
|
/* 2 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var mergeOptions = __webpack_require__(19)
|
|
|
|
/**
|
|
* Expose useful internals
|
|
*/
|
|
|
|
exports.util = _
|
|
exports.nextTick = _.nextTick
|
|
exports.config = __webpack_require__(20)
|
|
|
|
/**
|
|
* Each instance constructor, including Vue, has a unique
|
|
* cid. This enables us to create wrapped "child
|
|
* constructors" for prototypal inheritance and cache them.
|
|
*/
|
|
|
|
exports.cid = 0
|
|
var cid = 1
|
|
|
|
/**
|
|
* Class inehritance
|
|
*
|
|
* @param {Object} extendOptions
|
|
*/
|
|
|
|
exports.extend = function (extendOptions) {
|
|
extendOptions = extendOptions || {}
|
|
var Super = this
|
|
var Sub = createClass(extendOptions.name || 'VueComponent')
|
|
Sub.prototype = Object.create(Super.prototype)
|
|
Sub.prototype.constructor = Sub
|
|
Sub.cid = cid++
|
|
Sub.options = mergeOptions(
|
|
Super.options,
|
|
extendOptions
|
|
)
|
|
Sub['super'] = Super
|
|
// allow further extension
|
|
Sub.extend = Super.extend
|
|
// create asset registers, so extended classes
|
|
// can have their private assets too.
|
|
createAssetRegisters(Sub)
|
|
return Sub
|
|
}
|
|
|
|
/**
|
|
* A function that returns a sub-class constructor with the
|
|
* given name. This gives us much nicer output when
|
|
* logging instances in the console.
|
|
*
|
|
* @param {String} name
|
|
* @return {Function}
|
|
*/
|
|
|
|
function createClass (name) {
|
|
return new Function(
|
|
'return function ' + _.camelize(name, true) +
|
|
' (options) { this._init(options) }'
|
|
)()
|
|
}
|
|
|
|
/**
|
|
* Plugin system
|
|
*
|
|
* @param {Object} plugin
|
|
*/
|
|
|
|
exports.use = function (plugin) {
|
|
// additional parameters
|
|
var args = _.toArray(arguments, 1)
|
|
args.unshift(this)
|
|
if (typeof plugin.install === 'function') {
|
|
plugin.install.apply(plugin, args)
|
|
} else {
|
|
plugin.apply(null, args)
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Define asset registration methods on a constructor.
|
|
*
|
|
* @param {Function} Constructor
|
|
*/
|
|
|
|
var assetTypes = [
|
|
'directive',
|
|
'filter',
|
|
'partial',
|
|
'transition'
|
|
]
|
|
|
|
function createAssetRegisters (Constructor) {
|
|
|
|
/* Asset registration methods share the same signature:
|
|
*
|
|
* @param {String} id
|
|
* @param {*} definition
|
|
*/
|
|
|
|
assetTypes.forEach(function (type) {
|
|
Constructor[type] = function (id, definition) {
|
|
if (!definition) {
|
|
return this.options[type + 's'][id]
|
|
} else {
|
|
this.options[type + 's'][id] = definition
|
|
}
|
|
}
|
|
})
|
|
|
|
/**
|
|
* Component registration needs to automatically invoke
|
|
* Vue.extend on object values.
|
|
*
|
|
* @param {String} id
|
|
* @param {Object|Function} definition
|
|
*/
|
|
|
|
Constructor.component = function (id, definition) {
|
|
if (!definition) {
|
|
return this.options.components[id]
|
|
} else {
|
|
if (_.isPlainObject(definition)) {
|
|
definition.name = id
|
|
definition = _.Vue.extend(definition)
|
|
}
|
|
this.options.components[id] = definition
|
|
}
|
|
}
|
|
}
|
|
|
|
createAssetRegisters(exports)
|
|
|
|
/***/ },
|
|
/* 3 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var Watcher = __webpack_require__(21)
|
|
var Path = __webpack_require__(41)
|
|
var textParser = __webpack_require__(42)
|
|
var dirParser = __webpack_require__(43)
|
|
var expParser = __webpack_require__(44)
|
|
var filterRE = /[^|]\|[^|]/
|
|
|
|
/**
|
|
* Get the value from an expression on this vm.
|
|
*
|
|
* @param {String} exp
|
|
* @return {*}
|
|
*/
|
|
|
|
exports.$get = function (exp) {
|
|
var res = expParser.parse(exp)
|
|
if (res) {
|
|
return res.get.call(this, this)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the value from an expression on this vm.
|
|
* The expression must be a valid left-hand
|
|
* expression in an assignment.
|
|
*
|
|
* @param {String} exp
|
|
* @param {*} val
|
|
*/
|
|
|
|
exports.$set = function (exp, val) {
|
|
var res = expParser.parse(exp, true)
|
|
if (res && res.set) {
|
|
res.set.call(this, this, val)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a property on the VM
|
|
*
|
|
* @param {String} key
|
|
* @param {*} val
|
|
*/
|
|
|
|
exports.$add = function (key, val) {
|
|
this._data.$add(key, val)
|
|
}
|
|
|
|
/**
|
|
* Delete a property on the VM
|
|
*
|
|
* @param {String} key
|
|
*/
|
|
|
|
exports.$delete = function (key) {
|
|
this._data.$delete(key)
|
|
}
|
|
|
|
/**
|
|
* Watch an expression, trigger callback when its
|
|
* value changes.
|
|
*
|
|
* @param {String} exp
|
|
* @param {Function} cb
|
|
* @param {Boolean} [deep]
|
|
* @param {Boolean} [immediate]
|
|
* @return {Function} - unwatchFn
|
|
*/
|
|
|
|
exports.$watch = function (exp, cb, deep, immediate) {
|
|
var vm = this
|
|
var key = deep ? exp + '**deep**' : exp
|
|
var watcher = vm._userWatchers[key]
|
|
var wrappedCb = function (val, oldVal) {
|
|
cb.call(vm, val, oldVal)
|
|
}
|
|
if (!watcher) {
|
|
watcher = vm._userWatchers[key] =
|
|
new Watcher(vm, exp, wrappedCb, null, false, deep)
|
|
} else {
|
|
watcher.addCb(wrappedCb)
|
|
}
|
|
if (immediate) {
|
|
wrappedCb(watcher.value)
|
|
}
|
|
return function unwatchFn () {
|
|
watcher.removeCb(wrappedCb)
|
|
if (!watcher.active) {
|
|
vm._userWatchers[key] = null
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Evaluate a text directive, including filters.
|
|
*
|
|
* @param {String} text
|
|
* @return {String}
|
|
*/
|
|
|
|
exports.$eval = function (text) {
|
|
// check for filters.
|
|
if (filterRE.test(text)) {
|
|
var dir = dirParser.parse(text)[0]
|
|
// the filter regex check might give false positive
|
|
// for pipes inside strings, so it's possible that
|
|
// we don't get any filters here
|
|
return dir.filters
|
|
? _.applyFilters(
|
|
this.$get(dir.expression),
|
|
_.resolveFilters(this, dir.filters).read,
|
|
this
|
|
)
|
|
: this.$get(dir.expression)
|
|
} else {
|
|
// no filter
|
|
return this.$get(text)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Interpolate a piece of template text.
|
|
*
|
|
* @param {String} text
|
|
* @return {String}
|
|
*/
|
|
|
|
exports.$interpolate = function (text) {
|
|
var tokens = textParser.parse(text)
|
|
var vm = this
|
|
if (tokens) {
|
|
return tokens.length === 1
|
|
? vm.$eval(tokens[0].value)
|
|
: tokens.map(function (token) {
|
|
return token.tag
|
|
? vm.$eval(token.value)
|
|
: token.value
|
|
}).join('')
|
|
} else {
|
|
return text
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Log instance data as a plain JS object
|
|
* so that it is easier to inspect in console.
|
|
* This method assumes console is available.
|
|
*
|
|
* @param {String} [path]
|
|
*/
|
|
|
|
exports.$log = function (path) {
|
|
var data = path
|
|
? Path.get(this, path)
|
|
: this._data
|
|
console.log(JSON.parse(JSON.stringify(data)))
|
|
}
|
|
|
|
/***/ },
|
|
/* 4 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var transition = __webpack_require__(45)
|
|
|
|
/**
|
|
* Append instance to target
|
|
*
|
|
* @param {Node} target
|
|
* @param {Function} [cb]
|
|
* @param {Boolean} [withTransition] - defaults to true
|
|
*/
|
|
|
|
exports.$appendTo = function (target, cb, withTransition) {
|
|
target = query(target)
|
|
var targetIsDetached = !_.inDoc(target)
|
|
var op = withTransition === false || targetIsDetached
|
|
? append
|
|
: transition.append
|
|
insert(this, target, op, targetIsDetached, cb)
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Prepend instance to target
|
|
*
|
|
* @param {Node} target
|
|
* @param {Function} [cb]
|
|
* @param {Boolean} [withTransition] - defaults to true
|
|
*/
|
|
|
|
exports.$prependTo = function (target, cb, withTransition) {
|
|
target = query(target)
|
|
if (target.hasChildNodes()) {
|
|
this.$before(target.firstChild, cb, withTransition)
|
|
} else {
|
|
this.$appendTo(target, cb, withTransition)
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Insert instance before target
|
|
*
|
|
* @param {Node} target
|
|
* @param {Function} [cb]
|
|
* @param {Boolean} [withTransition] - defaults to true
|
|
*/
|
|
|
|
exports.$before = function (target, cb, withTransition) {
|
|
target = query(target)
|
|
var targetIsDetached = !_.inDoc(target)
|
|
var op = withTransition === false || targetIsDetached
|
|
? before
|
|
: transition.before
|
|
insert(this, target, op, targetIsDetached, cb)
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Insert instance after target
|
|
*
|
|
* @param {Node} target
|
|
* @param {Function} [cb]
|
|
* @param {Boolean} [withTransition] - defaults to true
|
|
*/
|
|
|
|
exports.$after = function (target, cb, withTransition) {
|
|
target = query(target)
|
|
if (target.nextSibling) {
|
|
this.$before(target.nextSibling, cb, withTransition)
|
|
} else {
|
|
this.$appendTo(target.parentNode, cb, withTransition)
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Remove instance from DOM
|
|
*
|
|
* @param {Function} [cb]
|
|
* @param {Boolean} [withTransition] - defaults to true
|
|
*/
|
|
|
|
exports.$remove = function (cb, withTransition) {
|
|
var inDoc = this._isAttached && _.inDoc(this.$el)
|
|
// if we are not in document, no need to check
|
|
// for transitions
|
|
if (!inDoc) withTransition = false
|
|
var op
|
|
var self = this
|
|
var realCb = function () {
|
|
if (inDoc) self._callHook('detached')
|
|
if (cb) cb()
|
|
}
|
|
if (
|
|
this._isBlock &&
|
|
!this._blockFragment.hasChildNodes()
|
|
) {
|
|
op = withTransition === false
|
|
? append
|
|
: transition.removeThenAppend
|
|
blockOp(this, this._blockFragment, op, realCb)
|
|
} else {
|
|
op = withTransition === false
|
|
? remove
|
|
: transition.remove
|
|
op(this.$el, this, realCb)
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Shared DOM insertion function.
|
|
*
|
|
* @param {Vue} vm
|
|
* @param {Element} target
|
|
* @param {Function} op
|
|
* @param {Boolean} targetIsDetached
|
|
* @param {Function} [cb]
|
|
*/
|
|
|
|
function insert (vm, target, op, targetIsDetached, cb) {
|
|
var shouldCallHook =
|
|
!targetIsDetached &&
|
|
!vm._isAttached &&
|
|
!_.inDoc(vm.$el)
|
|
if (vm._isBlock) {
|
|
blockOp(vm, target, op, cb)
|
|
} else {
|
|
op(vm.$el, target, vm, cb)
|
|
}
|
|
if (shouldCallHook) {
|
|
vm._callHook('attached')
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Execute a transition operation on a block instance,
|
|
* iterating through all its block nodes.
|
|
*
|
|
* @param {Vue} vm
|
|
* @param {Node} target
|
|
* @param {Function} op
|
|
* @param {Function} cb
|
|
*/
|
|
|
|
function blockOp (vm, target, op, cb) {
|
|
var current = vm._blockStart
|
|
var end = vm._blockEnd
|
|
var next
|
|
while (next !== end) {
|
|
next = current.nextSibling
|
|
op(current, target, vm)
|
|
current = next
|
|
}
|
|
op(end, target, vm, cb)
|
|
}
|
|
|
|
/**
|
|
* Check for selectors
|
|
*
|
|
* @param {String|Element} el
|
|
*/
|
|
|
|
function query (el) {
|
|
return typeof el === 'string'
|
|
? document.querySelector(el)
|
|
: el
|
|
}
|
|
|
|
/**
|
|
* Append operation that takes a callback.
|
|
*
|
|
* @param {Node} el
|
|
* @param {Node} target
|
|
* @param {Vue} vm - unused
|
|
* @param {Function} [cb]
|
|
*/
|
|
|
|
function append (el, target, vm, cb) {
|
|
target.appendChild(el)
|
|
if (cb) cb()
|
|
}
|
|
|
|
/**
|
|
* InsertBefore operation that takes a callback.
|
|
*
|
|
* @param {Node} el
|
|
* @param {Node} target
|
|
* @param {Vue} vm - unused
|
|
* @param {Function} [cb]
|
|
*/
|
|
|
|
function before (el, target, vm, cb) {
|
|
_.before(el, target)
|
|
if (cb) cb()
|
|
}
|
|
|
|
/**
|
|
* Remove operation that takes a callback.
|
|
*
|
|
* @param {Node} el
|
|
* @param {Vue} vm - unused
|
|
* @param {Function} [cb]
|
|
*/
|
|
|
|
function remove (el, vm, cb) {
|
|
_.remove(el)
|
|
if (cb) cb()
|
|
}
|
|
|
|
/***/ },
|
|
/* 5 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
|
|
/**
|
|
* Listen on the given `event` with `fn`.
|
|
*
|
|
* @param {String} event
|
|
* @param {Function} fn
|
|
*/
|
|
|
|
exports.$on = function (event, fn) {
|
|
(this._events[event] || (this._events[event] = []))
|
|
.push(fn)
|
|
modifyListenerCount(this, event, 1)
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Adds an `event` listener that will be invoked a single
|
|
* time then automatically removed.
|
|
*
|
|
* @param {String} event
|
|
* @param {Function} fn
|
|
*/
|
|
|
|
exports.$once = function (event, fn) {
|
|
var self = this
|
|
function on () {
|
|
self.$off(event, on)
|
|
fn.apply(this, arguments)
|
|
}
|
|
on.fn = fn
|
|
this.$on(event, on)
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Remove the given callback for `event` or all
|
|
* registered callbacks.
|
|
*
|
|
* @param {String} event
|
|
* @param {Function} fn
|
|
*/
|
|
|
|
exports.$off = function (event, fn) {
|
|
var cbs
|
|
// all
|
|
if (!arguments.length) {
|
|
if (this.$parent) {
|
|
for (event in this._events) {
|
|
cbs = this._events[event]
|
|
if (cbs) {
|
|
modifyListenerCount(this, event, -cbs.length)
|
|
}
|
|
}
|
|
}
|
|
this._events = {}
|
|
return this
|
|
}
|
|
// specific event
|
|
cbs = this._events[event]
|
|
if (!cbs) {
|
|
return this
|
|
}
|
|
if (arguments.length === 1) {
|
|
modifyListenerCount(this, event, -cbs.length)
|
|
this._events[event] = null
|
|
return this
|
|
}
|
|
// specific handler
|
|
var cb
|
|
var i = cbs.length
|
|
while (i--) {
|
|
cb = cbs[i]
|
|
if (cb === fn || cb.fn === fn) {
|
|
modifyListenerCount(this, event, -1)
|
|
cbs.splice(i, 1)
|
|
break
|
|
}
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Trigger an event on self.
|
|
*
|
|
* @param {String} event
|
|
*/
|
|
|
|
exports.$emit = function (event) {
|
|
this._eventCancelled = false
|
|
var cbs = this._events[event]
|
|
if (cbs) {
|
|
// avoid leaking arguments:
|
|
// http://jsperf.com/closure-with-arguments
|
|
var i = arguments.length - 1
|
|
var args = new Array(i)
|
|
while (i--) {
|
|
args[i] = arguments[i + 1]
|
|
}
|
|
i = 0
|
|
cbs = cbs.length > 1
|
|
? _.toArray(cbs)
|
|
: cbs
|
|
for (var l = cbs.length; i < l; i++) {
|
|
if (cbs[i].apply(this, args) === false) {
|
|
this._eventCancelled = true
|
|
}
|
|
}
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Recursively broadcast an event to all children instances.
|
|
*
|
|
* @param {String} event
|
|
* @param {...*} additional arguments
|
|
*/
|
|
|
|
exports.$broadcast = function (event) {
|
|
// if no child has registered for this event,
|
|
// then there's no need to broadcast.
|
|
if (!this._eventsCount[event]) return
|
|
var children = this._children
|
|
if (children) {
|
|
for (var i = 0, l = children.length; i < l; i++) {
|
|
var child = children[i]
|
|
child.$emit.apply(child, arguments)
|
|
if (!child._eventCancelled) {
|
|
child.$broadcast.apply(child, arguments)
|
|
}
|
|
}
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Recursively propagate an event up the parent chain.
|
|
*
|
|
* @param {String} event
|
|
* @param {...*} additional arguments
|
|
*/
|
|
|
|
exports.$dispatch = function () {
|
|
var parent = this.$parent
|
|
while (parent) {
|
|
parent.$emit.apply(parent, arguments)
|
|
parent = parent._eventCancelled
|
|
? null
|
|
: parent.$parent
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Modify the listener counts on all parents.
|
|
* This bookkeeping allows $broadcast to return early when
|
|
* no child has listened to a certain event.
|
|
*
|
|
* @param {Vue} vm
|
|
* @param {String} event
|
|
* @param {Number} count
|
|
*/
|
|
|
|
var hookRE = /^hook:/
|
|
function modifyListenerCount (vm, event, count) {
|
|
var parent = vm.$parent
|
|
// hooks do not get broadcasted so no need
|
|
// to do bookkeeping for them
|
|
if (!parent || !count || hookRE.test(event)) return
|
|
while (parent) {
|
|
parent._eventsCount[event] =
|
|
(parent._eventsCount[event] || 0) + count
|
|
parent = parent.$parent
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 6 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
|
|
/**
|
|
* Create a child instance that prototypally inehrits
|
|
* data on parent. To achieve that we create an intermediate
|
|
* constructor with its prototype pointing to parent.
|
|
*
|
|
* @param {Object} opts
|
|
* @param {Function} [BaseCtor]
|
|
* @return {Vue}
|
|
* @public
|
|
*/
|
|
|
|
exports.$addChild = function (opts, BaseCtor) {
|
|
BaseCtor = BaseCtor || _.Vue
|
|
opts = opts || {}
|
|
var parent = this
|
|
var ChildVue
|
|
var inherit = opts.inherit !== undefined
|
|
? opts.inherit
|
|
: BaseCtor.options.inherit
|
|
if (inherit) {
|
|
var ctors = parent._childCtors
|
|
if (!ctors) {
|
|
ctors = parent._childCtors = {}
|
|
}
|
|
ChildVue = ctors[BaseCtor.cid]
|
|
if (!ChildVue) {
|
|
var optionName = BaseCtor.options.name
|
|
var className = optionName
|
|
? _.camelize(optionName, true)
|
|
: 'VueComponent'
|
|
ChildVue = new Function(
|
|
'return function ' + className + ' (options) {' +
|
|
'this.constructor = ' + className + ';' +
|
|
'this._init(options) }'
|
|
)()
|
|
ChildVue.options = BaseCtor.options
|
|
ChildVue.prototype = this
|
|
ctors[BaseCtor.cid] = ChildVue
|
|
}
|
|
} else {
|
|
ChildVue = BaseCtor
|
|
}
|
|
opts._parent = parent
|
|
opts._root = parent.$root
|
|
var child = new ChildVue(opts)
|
|
if (!this._children) {
|
|
this._children = []
|
|
}
|
|
this._children.push(child)
|
|
return child
|
|
}
|
|
|
|
/***/ },
|
|
/* 7 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var compile = __webpack_require__(46)
|
|
|
|
/**
|
|
* Set instance target element and kick off the compilation
|
|
* process. The passed in `el` can be a selector string, an
|
|
* existing Element, or a DocumentFragment (for block
|
|
* instances).
|
|
*
|
|
* @param {Element|DocumentFragment|string} el
|
|
* @public
|
|
*/
|
|
|
|
exports.$mount = function (el) {
|
|
if (this._isCompiled) {
|
|
_.warn('$mount() should be called only once.')
|
|
return
|
|
}
|
|
if (!el) {
|
|
el = document.createElement('div')
|
|
} else if (typeof el === 'string') {
|
|
var selector = el
|
|
el = document.querySelector(el)
|
|
if (!el) {
|
|
_.warn('Cannot find element: ' + selector)
|
|
return
|
|
}
|
|
}
|
|
this._compile(el)
|
|
this._isCompiled = true
|
|
this._callHook('compiled')
|
|
if (_.inDoc(this.$el)) {
|
|
this._callHook('attached')
|
|
this._initDOMHooks()
|
|
ready.call(this)
|
|
} else {
|
|
this._initDOMHooks()
|
|
this.$once('hook:attached', ready)
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Mark an instance as ready.
|
|
*/
|
|
|
|
function ready () {
|
|
this._isAttached = true
|
|
this._isReady = true
|
|
this._callHook('ready')
|
|
}
|
|
|
|
/**
|
|
* Teardown an instance, unobserves the data, unbind all the
|
|
* directives, turn off all the event listeners, etc.
|
|
*
|
|
* @param {Boolean} remove - whether to remove the DOM node.
|
|
* @public
|
|
*/
|
|
|
|
exports.$destroy = function (remove) {
|
|
if (this._isBeingDestroyed) {
|
|
return
|
|
}
|
|
this._callHook('beforeDestroy')
|
|
this._isBeingDestroyed = true
|
|
var i
|
|
// remove self from parent. only necessary
|
|
// if parent is not being destroyed as well.
|
|
var parent = this.$parent
|
|
if (parent && !parent._isBeingDestroyed) {
|
|
i = parent._children.indexOf(this)
|
|
parent._children.splice(i, 1)
|
|
}
|
|
// destroy all children.
|
|
if (this._children) {
|
|
i = this._children.length
|
|
while (i--) {
|
|
this._children[i].$destroy()
|
|
}
|
|
}
|
|
// teardown all directives. this also tearsdown all
|
|
// directive-owned watchers.
|
|
i = this._directives.length
|
|
while (i--) {
|
|
this._directives[i]._teardown()
|
|
}
|
|
// teardown all user watchers.
|
|
for (i in this._userWatchers) {
|
|
this._userWatchers[i].teardown()
|
|
}
|
|
// remove reference to self on $el
|
|
if (this.$el) {
|
|
this.$el.__vue__ = null
|
|
}
|
|
// remove DOM element
|
|
var self = this
|
|
if (remove && this.$el) {
|
|
this.$remove(function () {
|
|
cleanup(self)
|
|
})
|
|
} else {
|
|
cleanup(self)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clean up to ensure garbage collection.
|
|
* This is called after the leave transition if there
|
|
* is any.
|
|
*
|
|
* @param {Vue} vm
|
|
*/
|
|
|
|
function cleanup (vm) {
|
|
// remove reference from data ob
|
|
vm._data.__ob__.removeVm(vm)
|
|
vm._data =
|
|
vm._watchers =
|
|
vm._userWatchers =
|
|
vm._watcherList =
|
|
vm.$el =
|
|
vm.$parent =
|
|
vm.$root =
|
|
vm._children =
|
|
vm._bindings =
|
|
vm._directives = null
|
|
// call the last hook...
|
|
vm._isDestroyed = true
|
|
vm._callHook('destroyed')
|
|
// turn off all instance listeners.
|
|
vm.$off()
|
|
}
|
|
|
|
/**
|
|
* Partially compile a piece of DOM and return a
|
|
* decompile function.
|
|
*
|
|
* @param {Element|DocumentFragment} el
|
|
* @return {Function}
|
|
*/
|
|
|
|
exports.$compile = function (el) {
|
|
return compile(el, this.$options, true)(this, el)
|
|
}
|
|
|
|
/***/ },
|
|
/* 8 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
// manipulation directives
|
|
exports.text = __webpack_require__(22)
|
|
exports.html = __webpack_require__(23)
|
|
exports.attr = __webpack_require__(24)
|
|
exports.show = __webpack_require__(25)
|
|
exports['class'] = __webpack_require__(26)
|
|
exports.el = __webpack_require__(27)
|
|
exports.ref = __webpack_require__(28)
|
|
exports.cloak = __webpack_require__(29)
|
|
exports.style = __webpack_require__(30)
|
|
exports.partial = __webpack_require__(31)
|
|
exports.transition = __webpack_require__(32)
|
|
|
|
// event listener directives
|
|
exports.on = __webpack_require__(33)
|
|
exports.model = __webpack_require__(48)
|
|
|
|
// child vm directives
|
|
exports.component = __webpack_require__(34)
|
|
exports.repeat = __webpack_require__(35)
|
|
exports['if'] = __webpack_require__(36)
|
|
exports['with'] = __webpack_require__(37)
|
|
|
|
/***/ },
|
|
/* 9 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
|
|
/**
|
|
* Stringify value.
|
|
*
|
|
* @param {Number} indent
|
|
*/
|
|
|
|
exports.json = function (value, indent) {
|
|
return JSON.stringify(value, null, Number(indent) || 2)
|
|
}
|
|
|
|
/**
|
|
* 'abc' => 'Abc'
|
|
*/
|
|
|
|
exports.capitalize = function (value) {
|
|
if (!value && value !== 0) return ''
|
|
value = value.toString()
|
|
return value.charAt(0).toUpperCase() + value.slice(1)
|
|
}
|
|
|
|
/**
|
|
* 'abc' => 'ABC'
|
|
*/
|
|
|
|
exports.uppercase = function (value) {
|
|
return (value || value === 0)
|
|
? value.toString().toUpperCase()
|
|
: ''
|
|
}
|
|
|
|
/**
|
|
* 'AbC' => 'abc'
|
|
*/
|
|
|
|
exports.lowercase = function (value) {
|
|
return (value || value === 0)
|
|
? value.toString().toLowerCase()
|
|
: ''
|
|
}
|
|
|
|
/**
|
|
* 12345 => $12,345.00
|
|
*
|
|
* @param {String} sign
|
|
*/
|
|
|
|
var digitsRE = /(\d{3})(?=\d)/g
|
|
|
|
exports.currency = function (value, sign) {
|
|
value = parseFloat(value)
|
|
if (!value && value !== 0) return ''
|
|
sign = sign || '$'
|
|
var s = Math.floor(Math.abs(value)).toString(),
|
|
i = s.length % 3,
|
|
h = i > 0
|
|
? (s.slice(0, i) + (s.length > 3 ? ',' : ''))
|
|
: '',
|
|
f = '.' + value.toFixed(2).slice(-2)
|
|
return (value < 0 ? '-' : '') +
|
|
sign + h + s.slice(i).replace(digitsRE, '$1,') + f
|
|
}
|
|
|
|
/**
|
|
* 'item' => 'items'
|
|
*
|
|
* @params
|
|
* 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']
|
|
*/
|
|
|
|
exports.pluralize = function (value) {
|
|
var args = _.toArray(arguments, 1)
|
|
return args.length > 1
|
|
? (args[value % 10 - 1] || args[args.length - 1])
|
|
: (args[0] + (value === 1 ? '' : 's'))
|
|
}
|
|
|
|
/**
|
|
* A special filter that takes a handler function,
|
|
* wraps it so it only gets triggered on specific
|
|
* keypresses. v-on only.
|
|
*
|
|
* @param {String} key
|
|
*/
|
|
|
|
var keyCodes = {
|
|
enter : 13,
|
|
tab : 9,
|
|
'delete' : 46,
|
|
up : 38,
|
|
left : 37,
|
|
right : 39,
|
|
down : 40,
|
|
esc : 27
|
|
}
|
|
|
|
exports.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)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Install special array filters
|
|
*/
|
|
|
|
_.extend(exports, __webpack_require__(38))
|
|
|
|
/***/ },
|
|
/* 10 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var mergeOptions = __webpack_require__(19)
|
|
|
|
/**
|
|
* The main init sequence. This is called for every
|
|
* instance, including ones that are created from extended
|
|
* constructors.
|
|
*
|
|
* @param {Object} options - this options object should be
|
|
* the result of merging class
|
|
* options and the options passed
|
|
* in to the constructor.
|
|
*/
|
|
|
|
exports._init = function (options) {
|
|
|
|
options = options || {}
|
|
|
|
this.$el = null
|
|
this.$parent = options._parent
|
|
this.$root = options._root || this
|
|
this.$ = {} // child vm references
|
|
this.$$ = {} // element references
|
|
this._watcherList = [] // all watchers as an array
|
|
this._watchers = {} // internal watchers as a hash
|
|
this._userWatchers = {} // user watchers as a hash
|
|
this._directives = [] // all directives
|
|
|
|
// a flag to avoid this being observed
|
|
this._isVue = true
|
|
|
|
// events bookkeeping
|
|
this._events = {} // registered callbacks
|
|
this._eventsCount = {} // for $broadcast optimization
|
|
this._eventCancelled = false // for event cancellation
|
|
|
|
// block instance properties
|
|
this._isBlock = false
|
|
this._blockStart = // @type {CommentNode}
|
|
this._blockEnd = null // @type {CommentNode}
|
|
|
|
// lifecycle state
|
|
this._isCompiled =
|
|
this._isDestroyed =
|
|
this._isReady =
|
|
this._isAttached =
|
|
this._isBeingDestroyed = false
|
|
|
|
// children
|
|
this._children = // @type {Array}
|
|
this._childCtors = null // @type {Object} - hash to cache
|
|
// child constructors
|
|
|
|
// merge options.
|
|
options = this.$options = mergeOptions(
|
|
this.constructor.options,
|
|
options,
|
|
this
|
|
)
|
|
|
|
// set data after merge.
|
|
this._data = options.data || {}
|
|
|
|
// initialize data observation and scope inheritance.
|
|
this._initScope()
|
|
|
|
// setup event system and option events.
|
|
this._initEvents()
|
|
|
|
// call created hook
|
|
this._callHook('created')
|
|
|
|
// if `el` option is passed, start compilation.
|
|
if (options.el) {
|
|
this.$mount(options.el)
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 11 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var inDoc = _.inDoc
|
|
|
|
/**
|
|
* Setup the instance's option events & watchers.
|
|
* If the value is a string, we pull it from the
|
|
* instance's methods by name.
|
|
*/
|
|
|
|
exports._initEvents = function () {
|
|
var options = this.$options
|
|
registerCallbacks(this, '$on', options.events)
|
|
registerCallbacks(this, '$watch', options.watch)
|
|
}
|
|
|
|
/**
|
|
* Register callbacks for option events and watchers.
|
|
*
|
|
* @param {Vue} vm
|
|
* @param {String} action
|
|
* @param {Object} hash
|
|
*/
|
|
|
|
function registerCallbacks (vm, action, hash) {
|
|
if (!hash) return
|
|
var handlers, key, i, j
|
|
for (key in hash) {
|
|
handlers = hash[key]
|
|
if (_.isArray(handlers)) {
|
|
for (i = 0, j = handlers.length; i < j; i++) {
|
|
register(vm, action, key, handlers[i])
|
|
}
|
|
} else {
|
|
register(vm, action, key, handlers)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper to register an event/watch callback.
|
|
*
|
|
* @param {Vue} vm
|
|
* @param {String} action
|
|
* @param {String} key
|
|
* @param {*} handler
|
|
*/
|
|
|
|
function register (vm, action, key, handler) {
|
|
var type = typeof handler
|
|
if (type === 'function') {
|
|
vm[action](key, handler)
|
|
} else if (type === 'string') {
|
|
var methods = vm.$options.methods
|
|
var method = methods && methods[handler]
|
|
if (method) {
|
|
vm[action](key, method)
|
|
} else {
|
|
_.warn(
|
|
'Unknown method: "' + handler + '" when ' +
|
|
'registering callback for ' + action +
|
|
': "' + key + '".'
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setup recursive attached/detached calls
|
|
*/
|
|
|
|
exports._initDOMHooks = function () {
|
|
this.$on('hook:attached', onAttached)
|
|
this.$on('hook:detached', onDetached)
|
|
}
|
|
|
|
/**
|
|
* Callback to recursively call attached hook on children
|
|
*/
|
|
|
|
function onAttached () {
|
|
this._isAttached = true
|
|
var children = this._children
|
|
if (!children) return
|
|
for (var i = 0, l = children.length; i < l; i++) {
|
|
var child = children[i]
|
|
if (!child._isAttached && inDoc(child.$el)) {
|
|
child._callHook('attached')
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Callback to recursively call detached hook on children
|
|
*/
|
|
|
|
function onDetached () {
|
|
this._isAttached = false
|
|
var children = this._children
|
|
if (!children) return
|
|
for (var i = 0, l = children.length; i < l; i++) {
|
|
var child = children[i]
|
|
if (child._isAttached && !inDoc(child.$el)) {
|
|
child._callHook('detached')
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Trigger all handlers for a hook
|
|
*
|
|
* @param {String} hook
|
|
*/
|
|
|
|
exports._callHook = function (hook) {
|
|
var handlers = this.$options[hook]
|
|
if (handlers) {
|
|
for (var i = 0, j = handlers.length; i < j; i++) {
|
|
handlers[i].call(this)
|
|
}
|
|
}
|
|
this.$emit('hook:' + hook)
|
|
}
|
|
|
|
/***/ },
|
|
/* 12 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var Observer = __webpack_require__(49)
|
|
var Binding = __webpack_require__(39)
|
|
|
|
/**
|
|
* Setup the scope of an instance, which contains:
|
|
* - observed data
|
|
* - computed properties
|
|
* - user methods
|
|
* - meta properties
|
|
*/
|
|
|
|
exports._initScope = function () {
|
|
this._initData()
|
|
this._initComputed()
|
|
this._initMethods()
|
|
this._initMeta()
|
|
}
|
|
|
|
/**
|
|
* Initialize the data.
|
|
*/
|
|
|
|
exports._initData = function () {
|
|
// proxy data on instance
|
|
var data = this._data
|
|
var keys = Object.keys(data)
|
|
var i = keys.length
|
|
var key
|
|
while (i--) {
|
|
key = keys[i]
|
|
if (!_.isReserved(key)) {
|
|
this._proxy(key)
|
|
}
|
|
}
|
|
// observe data
|
|
Observer.create(data).addVm(this)
|
|
}
|
|
|
|
/**
|
|
* Swap the isntance's $data. Called in $data's setter.
|
|
*
|
|
* @param {Object} newData
|
|
*/
|
|
|
|
exports._setData = function (newData) {
|
|
newData = newData || {}
|
|
var oldData = this._data
|
|
this._data = newData
|
|
var keys, key, i
|
|
// unproxy keys not present in new data
|
|
keys = Object.keys(oldData)
|
|
i = keys.length
|
|
while (i--) {
|
|
key = keys[i]
|
|
if (!_.isReserved(key) && !(key in newData)) {
|
|
this._unproxy(key)
|
|
}
|
|
}
|
|
// proxy keys not already proxied,
|
|
// and trigger change for changed values
|
|
keys = Object.keys(newData)
|
|
i = keys.length
|
|
while (i--) {
|
|
key = keys[i]
|
|
if (!this.hasOwnProperty(key) && !_.isReserved(key)) {
|
|
// new property
|
|
this._proxy(key)
|
|
}
|
|
}
|
|
oldData.__ob__.removeVm(this)
|
|
Observer.create(newData).addVm(this)
|
|
this._digest()
|
|
}
|
|
|
|
/**
|
|
* Proxy a property, so that
|
|
* vm.prop === vm._data.prop
|
|
*
|
|
* @param {String} key
|
|
*/
|
|
|
|
exports._proxy = function (key) {
|
|
// need to store ref to self here
|
|
// because these getter/setters might
|
|
// be called by child instances!
|
|
var self = this
|
|
Object.defineProperty(self, key, {
|
|
configurable: true,
|
|
enumerable: true,
|
|
get: function proxyGetter () {
|
|
return self._data[key]
|
|
},
|
|
set: function proxySetter (val) {
|
|
self._data[key] = val
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Unproxy a property.
|
|
*
|
|
* @param {String} key
|
|
*/
|
|
|
|
exports._unproxy = function (key) {
|
|
delete this[key]
|
|
}
|
|
|
|
/**
|
|
* Force update on every watcher in scope.
|
|
*/
|
|
|
|
exports._digest = function () {
|
|
var i = this._watcherList.length
|
|
while (i--) {
|
|
this._watcherList[i].update()
|
|
}
|
|
var children = this._children
|
|
var child
|
|
if (children) {
|
|
i = children.length
|
|
while (i--) {
|
|
child = children[i]
|
|
if (child.$options.inherit) {
|
|
child._digest()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setup computed properties. They are essentially
|
|
* special getter/setters
|
|
*/
|
|
|
|
function noop () {}
|
|
exports._initComputed = function () {
|
|
var computed = this.$options.computed
|
|
if (computed) {
|
|
for (var key in computed) {
|
|
var userDef = computed[key]
|
|
var def = {
|
|
enumerable: true,
|
|
configurable: true
|
|
}
|
|
if (typeof userDef === 'function') {
|
|
def.get = _.bind(userDef, this)
|
|
def.set = noop
|
|
} else {
|
|
def.get = userDef.get
|
|
? _.bind(userDef.get, this)
|
|
: noop
|
|
def.set = userDef.set
|
|
? _.bind(userDef.set, this)
|
|
: noop
|
|
}
|
|
Object.defineProperty(this, key, def)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setup instance methods. Methods must be bound to the
|
|
* instance since they might be called by children
|
|
* inheriting them.
|
|
*/
|
|
|
|
exports._initMethods = function () {
|
|
var methods = this.$options.methods
|
|
if (methods) {
|
|
for (var key in methods) {
|
|
this[key] = _.bind(methods[key], this)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialize meta information like $index, $key & $value.
|
|
*/
|
|
|
|
exports._initMeta = function () {
|
|
var metas = this.$options._meta
|
|
if (metas) {
|
|
for (var key in metas) {
|
|
this._defineMeta(key, metas[key])
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Define a meta property, e.g $index, $key, $value
|
|
* which only exists on the vm instance but not in $data.
|
|
*
|
|
* @param {String} key
|
|
* @param {*} value
|
|
*/
|
|
|
|
exports._defineMeta = function (key, value) {
|
|
var binding = new Binding()
|
|
Object.defineProperty(this, key, {
|
|
enumerable: true,
|
|
configurable: true,
|
|
get: function metaGetter () {
|
|
if (Observer.target) {
|
|
Observer.target.addDep(binding)
|
|
}
|
|
return value
|
|
},
|
|
set: function metaSetter (val) {
|
|
if (val !== value) {
|
|
value = val
|
|
binding.notify()
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
/***/ },
|
|
/* 13 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var Directive = __webpack_require__(40)
|
|
var compile = __webpack_require__(46)
|
|
var transclude = __webpack_require__(47)
|
|
|
|
/**
|
|
* Transclude, compile and link element.
|
|
*
|
|
* If a pre-compiled linker is available, that means the
|
|
* passed in element will be pre-transcluded and compiled
|
|
* as well - all we need to do is to call the linker.
|
|
*
|
|
* Otherwise we need to call transclude/compile/link here.
|
|
*
|
|
* @param {Element} el
|
|
* @return {Element}
|
|
*/
|
|
|
|
exports._compile = function (el) {
|
|
var options = this.$options
|
|
if (options._linker) {
|
|
this._initElement(el)
|
|
options._linker(this, el)
|
|
} else {
|
|
var raw = el
|
|
el = transclude(el, options)
|
|
this._initElement(el)
|
|
var linker = compile(el, options)
|
|
linker(this, el)
|
|
if (options.replace) {
|
|
_.replace(raw, el)
|
|
}
|
|
}
|
|
return el
|
|
}
|
|
|
|
/**
|
|
* Initialize instance element. Called in the public
|
|
* $mount() method.
|
|
*
|
|
* @param {Element} el
|
|
*/
|
|
|
|
exports._initElement = function (el) {
|
|
if (el instanceof DocumentFragment) {
|
|
this._isBlock = true
|
|
this.$el = this._blockStart = el.firstChild
|
|
this._blockEnd = el.lastChild
|
|
this._blockFragment = el
|
|
} else {
|
|
this.$el = el
|
|
}
|
|
this.$el.__vue__ = this
|
|
this._callHook('beforeCompile')
|
|
}
|
|
|
|
/**
|
|
* Create and bind a directive to an element.
|
|
*
|
|
* @param {String} name - directive name
|
|
* @param {Node} node - target node
|
|
* @param {Object} desc - parsed directive descriptor
|
|
* @param {Object} def - directive definition object
|
|
* @param {Function} [linker] - pre-compiled linker fn
|
|
*/
|
|
|
|
exports._bindDir = function (name, node, desc, def, linker) {
|
|
this._directives.push(
|
|
new Directive(name, node, this, desc, def, linker)
|
|
)
|
|
}
|
|
|
|
/***/ },
|
|
/* 14 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Check is a string starts with $ or _
|
|
*
|
|
* @param {String} str
|
|
* @return {Boolean}
|
|
*/
|
|
|
|
exports.isReserved = function (str) {
|
|
var c = str.charCodeAt(0)
|
|
return c === 0x24 || c === 0x5F
|
|
}
|
|
|
|
/**
|
|
* Guard text output, make sure undefined outputs
|
|
* empty string
|
|
*
|
|
* @param {*} value
|
|
* @return {String}
|
|
*/
|
|
|
|
exports.toString = function (value) {
|
|
return value == null
|
|
? ''
|
|
: value.toString()
|
|
}
|
|
|
|
/**
|
|
* Check and convert possible numeric numbers before
|
|
* setting back to data
|
|
*
|
|
* @param {*} value
|
|
* @return {*|Number}
|
|
*/
|
|
|
|
exports.toNumber = function (value) {
|
|
return (
|
|
isNaN(value) ||
|
|
value === null ||
|
|
typeof value === 'boolean'
|
|
) ? value
|
|
: Number(value)
|
|
}
|
|
|
|
/**
|
|
* Strip quotes from a string
|
|
*
|
|
* @param {String} str
|
|
* @return {String | false}
|
|
*/
|
|
|
|
exports.stripQuotes = function (str) {
|
|
var a = str.charCodeAt(0)
|
|
var b = str.charCodeAt(str.length - 1)
|
|
return a === b && (a === 0x22 || a === 0x27)
|
|
? str.slice(1, -1)
|
|
: false
|
|
}
|
|
|
|
/**
|
|
* Camelize a hyphen-delmited string.
|
|
*
|
|
* @param {String} str
|
|
* @return {String}
|
|
*/
|
|
|
|
var camelRE = /[-_](\w)/g
|
|
var capitalCamelRE = /(?:^|[-_])(\w)/g
|
|
|
|
exports.camelize = function (str, cap) {
|
|
var RE = cap ? capitalCamelRE : camelRE
|
|
return str.replace(RE, function (_, c) {
|
|
return c ? c.toUpperCase () : '';
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Simple bind, faster than native
|
|
*
|
|
* @param {Function} fn
|
|
* @param {Object} ctx
|
|
* @return {Function}
|
|
*/
|
|
|
|
exports.bind = function (fn, ctx) {
|
|
return function () {
|
|
return fn.apply(ctx, arguments)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convert an Array-like object to a real Array.
|
|
*
|
|
* @param {Array-like} list
|
|
* @param {Number} [start] - start index
|
|
* @return {Array}
|
|
*/
|
|
|
|
exports.toArray = function (list, start) {
|
|
start = start || 0
|
|
var i = list.length - start
|
|
var ret = new Array(i)
|
|
while (i--) {
|
|
ret[i] = list[i + start]
|
|
}
|
|
return ret
|
|
}
|
|
|
|
/**
|
|
* Mix properties into target object.
|
|
*
|
|
* @param {Object} to
|
|
* @param {Object} from
|
|
*/
|
|
|
|
exports.extend = function (to, from) {
|
|
for (var key in from) {
|
|
to[key] = from[key]
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Quick object check - this is primarily used to tell
|
|
* Objects from primitive values when we know the value
|
|
* is a JSON-compliant type.
|
|
*
|
|
* @param {*} obj
|
|
* @return {Boolean}
|
|
*/
|
|
|
|
exports.isObject = function (obj) {
|
|
return obj && typeof obj === 'object'
|
|
}
|
|
|
|
/**
|
|
* Strict object type check. Only returns true
|
|
* for plain JavaScript objects.
|
|
*
|
|
* @param {*} obj
|
|
* @return {Boolean}
|
|
*/
|
|
|
|
var toString = Object.prototype.toString
|
|
exports.isPlainObject = function (obj) {
|
|
return toString.call(obj) === '[object Object]'
|
|
}
|
|
|
|
/**
|
|
* Array type check.
|
|
*
|
|
* @param {*} obj
|
|
* @return {Boolean}
|
|
*/
|
|
|
|
exports.isArray = function (obj) {
|
|
return Array.isArray(obj)
|
|
}
|
|
|
|
/**
|
|
* Define a non-enumerable property
|
|
*
|
|
* @param {Object} obj
|
|
* @param {String} key
|
|
* @param {*} val
|
|
* @param {Boolean} [enumerable]
|
|
*/
|
|
|
|
exports.define = function (obj, key, val, enumerable) {
|
|
Object.defineProperty(obj, key, {
|
|
value : val,
|
|
enumerable : !!enumerable,
|
|
writable : true,
|
|
configurable : true
|
|
})
|
|
}
|
|
|
|
/***/ },
|
|
/* 15 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Can we use __proto__?
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
|
|
exports.hasProto = '__proto__' in {}
|
|
|
|
/**
|
|
* Indicates we have a window
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
|
|
var toString = Object.prototype.toString
|
|
var inBrowser = exports.inBrowser =
|
|
typeof window !== 'undefined' &&
|
|
toString.call(window) !== '[object Object]'
|
|
|
|
/**
|
|
* Defer a task to the start of the next event loop
|
|
*
|
|
* @param {Function} cb
|
|
* @param {Object} ctx
|
|
*/
|
|
|
|
var defer = inBrowser
|
|
? (window.requestAnimationFrame ||
|
|
window.webkitRequestAnimationFrame ||
|
|
setTimeout)
|
|
: setTimeout
|
|
|
|
exports.nextTick = function (cb, ctx) {
|
|
if (ctx) {
|
|
defer(function () { cb.call(ctx) }, 0)
|
|
} else {
|
|
defer(cb, 0)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Detect if we are in IE9...
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
|
|
exports.isIE9 =
|
|
inBrowser &&
|
|
navigator.userAgent.indexOf('MSIE 9.0') > 0
|
|
|
|
/**
|
|
* Sniff transition/animation events
|
|
*/
|
|
|
|
if (inBrowser && !exports.isIE9) {
|
|
var isWebkitTrans =
|
|
window.ontransitionend === undefined &&
|
|
window.onwebkittransitionend !== undefined
|
|
var isWebkitAnim =
|
|
window.onanimationend === undefined &&
|
|
window.onwebkitanimationend !== undefined
|
|
exports.transitionProp = isWebkitTrans
|
|
? 'WebkitTransition'
|
|
: 'transition'
|
|
exports.transitionEndEvent = isWebkitTrans
|
|
? 'webkitTransitionEnd'
|
|
: 'transitionend'
|
|
exports.animationProp = isWebkitAnim
|
|
? 'WebkitAnimation'
|
|
: 'animation'
|
|
exports.animationEndEvent = isWebkitAnim
|
|
? 'webkitAnimationEnd'
|
|
: 'animationend'
|
|
}
|
|
|
|
/***/ },
|
|
/* 16 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var config = __webpack_require__(20)
|
|
|
|
/**
|
|
* Check if a node is in the document.
|
|
*
|
|
* @param {Node} node
|
|
* @return {Boolean}
|
|
*/
|
|
|
|
var doc =
|
|
typeof document !== 'undefined' &&
|
|
document.documentElement
|
|
|
|
exports.inDoc = function (node) {
|
|
return doc && doc.contains(node)
|
|
}
|
|
|
|
/**
|
|
* Extract an attribute from a node.
|
|
*
|
|
* @param {Node} node
|
|
* @param {String} attr
|
|
*/
|
|
|
|
exports.attr = function (node, attr) {
|
|
attr = config.prefix + attr
|
|
var val = node.getAttribute(attr)
|
|
if (val !== null) {
|
|
node.removeAttribute(attr)
|
|
}
|
|
return val
|
|
}
|
|
|
|
/**
|
|
* Insert el before target
|
|
*
|
|
* @param {Element} el
|
|
* @param {Element} target
|
|
*/
|
|
|
|
exports.before = function (el, target) {
|
|
target.parentNode.insertBefore(el, target)
|
|
}
|
|
|
|
/**
|
|
* Insert el after target
|
|
*
|
|
* @param {Element} el
|
|
* @param {Element} target
|
|
*/
|
|
|
|
exports.after = function (el, target) {
|
|
if (target.nextSibling) {
|
|
exports.before(el, target.nextSibling)
|
|
} else {
|
|
target.parentNode.appendChild(el)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove el from DOM
|
|
*
|
|
* @param {Element} el
|
|
*/
|
|
|
|
exports.remove = function (el) {
|
|
el.parentNode.removeChild(el)
|
|
}
|
|
|
|
/**
|
|
* Prepend el to target
|
|
*
|
|
* @param {Element} el
|
|
* @param {Element} target
|
|
*/
|
|
|
|
exports.prepend = function (el, target) {
|
|
if (target.firstChild) {
|
|
exports.before(el, target.firstChild)
|
|
} else {
|
|
target.appendChild(el)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Replace target with el
|
|
*
|
|
* @param {Element} target
|
|
* @param {Element} el
|
|
*/
|
|
|
|
exports.replace = function (target, el) {
|
|
var parent = target.parentNode
|
|
if (parent) {
|
|
parent.replaceChild(el, target)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Copy attributes from one element to another.
|
|
*
|
|
* @param {Element} from
|
|
* @param {Element} to
|
|
*/
|
|
|
|
exports.copyAttributes = function (from, to) {
|
|
if (from.hasAttributes()) {
|
|
var attrs = from.attributes
|
|
for (var i = 0, l = attrs.length; i < l; i++) {
|
|
var attr = attrs[i]
|
|
to.setAttribute(attr.name, attr.value)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add event listener shorthand.
|
|
*
|
|
* @param {Element} el
|
|
* @param {String} event
|
|
* @param {Function} cb
|
|
*/
|
|
|
|
exports.on = function (el, event, cb) {
|
|
el.addEventListener(event, cb)
|
|
}
|
|
|
|
/**
|
|
* Remove event listener shorthand.
|
|
*
|
|
* @param {Element} el
|
|
* @param {String} event
|
|
* @param {Function} cb
|
|
*/
|
|
|
|
exports.off = function (el, event, cb) {
|
|
el.removeEventListener(event, cb)
|
|
}
|
|
|
|
/**
|
|
* Add class with compatibility for IE & SVG
|
|
*
|
|
* @param {Element} el
|
|
* @param {Strong} cls
|
|
*/
|
|
|
|
exports.addClass = function (el, cls) {
|
|
if (el.classList) {
|
|
el.classList.add(cls)
|
|
} else {
|
|
var cur = ' ' + (el.getAttribute('class') || '') + ' '
|
|
if (cur.indexOf(' ' + cls + ' ') < 0) {
|
|
el.setAttribute('class', (cur + cls).trim())
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove class with compatibility for IE & SVG
|
|
*
|
|
* @param {Element} el
|
|
* @param {Strong} cls
|
|
*/
|
|
|
|
exports.removeClass = function (el, cls) {
|
|
if (el.classList) {
|
|
el.classList.remove(cls)
|
|
} else {
|
|
var cur = ' ' + (el.getAttribute('class') || '') + ' '
|
|
var tar = ' ' + cls + ' '
|
|
while (cur.indexOf(tar) >= 0) {
|
|
cur = cur.replace(tar, ' ')
|
|
}
|
|
el.setAttribute('class', cur.trim())
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 17 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(18)
|
|
|
|
/**
|
|
* Resolve read & write filters for a vm instance. The
|
|
* filters descriptor Array comes from the directive parser.
|
|
*
|
|
* This is extracted into its own utility so it can
|
|
* be used in multiple scenarios.
|
|
*
|
|
* @param {Vue} vm
|
|
* @param {Array<Object>} filters
|
|
* @param {Object} [target]
|
|
* @return {Object}
|
|
*/
|
|
|
|
exports.resolveFilters = function (vm, filters, target) {
|
|
if (!filters) {
|
|
return
|
|
}
|
|
var res = target || {}
|
|
// var registry = vm.$options.filters
|
|
filters.forEach(function (f) {
|
|
var def = vm.$options.filters[f.name]
|
|
_.assertAsset(def, 'filter', f.name)
|
|
if (!def) return
|
|
var args = f.args
|
|
var reader, writer
|
|
if (typeof def === 'function') {
|
|
reader = def
|
|
} else {
|
|
reader = def.read
|
|
writer = def.write
|
|
}
|
|
if (reader) {
|
|
if (!res.read) res.read = []
|
|
res.read.push(function (value) {
|
|
return args
|
|
? reader.apply(vm, [value].concat(args))
|
|
: reader.call(vm, value)
|
|
})
|
|
}
|
|
if (writer) {
|
|
if (!res.write) res.write = []
|
|
res.write.push(function (value, oldVal) {
|
|
return args
|
|
? writer.apply(vm, [value, oldVal].concat(args))
|
|
: writer.call(vm, value, oldVal)
|
|
})
|
|
}
|
|
})
|
|
return res
|
|
}
|
|
|
|
/**
|
|
* Apply filters to a value
|
|
*
|
|
* @param {*} value
|
|
* @param {Array} filters
|
|
* @param {Vue} vm
|
|
* @param {*} oldVal
|
|
* @return {*}
|
|
*/
|
|
|
|
exports.applyFilters = function (value, filters, vm, oldVal) {
|
|
if (!filters) {
|
|
return value
|
|
}
|
|
for (var i = 0, l = filters.length; i < l; i++) {
|
|
value = filters[i].call(vm, value, oldVal)
|
|
}
|
|
return value
|
|
}
|
|
|
|
/***/ },
|
|
/* 18 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var config = __webpack_require__(20)
|
|
|
|
/**
|
|
* Enable debug utilities. The enableDebug() function and
|
|
* all _.log() & _.warn() calls will be dropped in the
|
|
* minified production build.
|
|
*/
|
|
|
|
enableDebug()
|
|
|
|
function enableDebug () {
|
|
var hasConsole = typeof console !== 'undefined'
|
|
|
|
/**
|
|
* Log a message.
|
|
*
|
|
* @param {String} msg
|
|
*/
|
|
|
|
exports.log = function (msg) {
|
|
if (hasConsole && config.debug) {
|
|
console.log('[Vue info]: ' + msg)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* We've got a problem here.
|
|
*
|
|
* @param {String} msg
|
|
*/
|
|
|
|
exports.warn = function (msg) {
|
|
if (hasConsole && !config.silent) {
|
|
console.warn('[Vue warn]: ' + msg)
|
|
if (config.debug && console.trace) {
|
|
console.trace()
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assert asset exists
|
|
*/
|
|
|
|
exports.assertAsset = function (val, type, id) {
|
|
if (!val) {
|
|
exports.warn('Failed to resolve ' + type + ': ' + id)
|
|
}
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 19 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var extend = _.extend
|
|
|
|
/**
|
|
* Option overwriting strategies are functions that handle
|
|
* how to merge a parent option value and a child option
|
|
* value into the final value.
|
|
*
|
|
* All strategy functions follow the same signature:
|
|
*
|
|
* @param {*} parentVal
|
|
* @param {*} childVal
|
|
* @param {Vue} [vm]
|
|
*/
|
|
|
|
var strats = Object.create(null)
|
|
|
|
/**
|
|
* Data
|
|
*/
|
|
|
|
strats.data = function (parentVal, childVal, vm) {
|
|
// in a class merge, both should be functions
|
|
// so we just return child if it exists
|
|
if (!vm) {
|
|
if (childVal && typeof childVal !== 'function') {
|
|
_.warn(
|
|
'The "data" option should be a function ' +
|
|
'that returns a per-instance value in component ' +
|
|
'definitions.'
|
|
)
|
|
return
|
|
}
|
|
return childVal || parentVal
|
|
}
|
|
var instanceData = typeof childVal === 'function'
|
|
? childVal.call(vm)
|
|
: childVal
|
|
var defaultData = typeof parentVal === 'function'
|
|
? parentVal.call(vm)
|
|
: undefined
|
|
if (instanceData) {
|
|
// mix default data into instance data
|
|
for (var key in defaultData) {
|
|
if (!instanceData.hasOwnProperty(key)) {
|
|
instanceData.$add(key, defaultData[key])
|
|
}
|
|
}
|
|
return instanceData
|
|
} else {
|
|
return defaultData
|
|
}
|
|
}
|
|
|
|
/**
|
|
* El
|
|
*/
|
|
|
|
strats.el = function (parentVal, childVal, vm) {
|
|
if (!vm && childVal && typeof childVal !== 'function') {
|
|
_.warn(
|
|
'The "el" option should be a function ' +
|
|
'that returns a per-instance value in component ' +
|
|
'definitions.'
|
|
)
|
|
return
|
|
}
|
|
var ret = childVal || parentVal
|
|
// invoke the element factory if this is instance merge
|
|
return vm && typeof ret === 'function'
|
|
? ret.call(vm)
|
|
: ret
|
|
}
|
|
|
|
/**
|
|
* Hooks and param attributes are merged as arrays.
|
|
*/
|
|
|
|
strats.created =
|
|
strats.ready =
|
|
strats.attached =
|
|
strats.detached =
|
|
strats.beforeCompile =
|
|
strats.compiled =
|
|
strats.beforeDestroy =
|
|
strats.destroyed =
|
|
strats.paramAttributes = function (parentVal, childVal) {
|
|
return childVal
|
|
? parentVal
|
|
? parentVal.concat(childVal)
|
|
: _.isArray(childVal)
|
|
? childVal
|
|
: [childVal]
|
|
: parentVal
|
|
}
|
|
|
|
/**
|
|
* Assets
|
|
*
|
|
* When a vm is present (instance creation), we need to do
|
|
* a three-way merge between constructor options, instance
|
|
* options and parent options.
|
|
*/
|
|
|
|
strats.directives =
|
|
strats.filters =
|
|
strats.partials =
|
|
strats.transitions =
|
|
strats.components = function (parentVal, childVal, vm, key) {
|
|
var ret = Object.create(
|
|
vm && vm.$parent
|
|
? vm.$parent.$options[key]
|
|
: _.Vue.options[key]
|
|
)
|
|
if (parentVal) {
|
|
var keys = Object.keys(parentVal)
|
|
var i = keys.length
|
|
var field
|
|
while (i--) {
|
|
field = keys[i]
|
|
ret[field] = parentVal[field]
|
|
}
|
|
}
|
|
if (childVal) extend(ret, childVal)
|
|
return ret
|
|
}
|
|
|
|
/**
|
|
* Events & Watchers.
|
|
*
|
|
* Events & watchers hashes should not overwrite one
|
|
* another, so we merge them as arrays.
|
|
*/
|
|
|
|
strats.watch =
|
|
strats.events = function (parentVal, childVal) {
|
|
if (!childVal) return parentVal
|
|
if (!parentVal) return childVal
|
|
var ret = {}
|
|
extend(ret, parentVal)
|
|
for (var key in childVal) {
|
|
var parent = ret[key]
|
|
var child = childVal[key]
|
|
ret[key] = parent
|
|
? parent.concat(child)
|
|
: [child]
|
|
}
|
|
return ret
|
|
}
|
|
|
|
/**
|
|
* Other object hashes.
|
|
*/
|
|
|
|
strats.methods =
|
|
strats.computed = function (parentVal, childVal) {
|
|
if (!childVal) return parentVal
|
|
if (!parentVal) return childVal
|
|
var ret = Object.create(parentVal)
|
|
extend(ret, childVal)
|
|
return ret
|
|
}
|
|
|
|
/**
|
|
* Default strategy.
|
|
*/
|
|
|
|
var defaultStrat = function (parentVal, childVal) {
|
|
return childVal === undefined
|
|
? parentVal
|
|
: childVal
|
|
}
|
|
|
|
/**
|
|
* Make sure component options get converted to actual
|
|
* constructors.
|
|
*
|
|
* @param {Object} components
|
|
*/
|
|
|
|
function guardComponents (components) {
|
|
if (components) {
|
|
var def
|
|
for (var key in components) {
|
|
def = components[key]
|
|
if (_.isPlainObject(def)) {
|
|
def.name = key
|
|
components[key] = _.Vue.extend(def)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Merge two option objects into a new one.
|
|
* Core utility used in both instantiation and inheritance.
|
|
*
|
|
* @param {Object} parent
|
|
* @param {Object} child
|
|
* @param {Vue} [vm] - if vm is present, indicates this is
|
|
* an instantiation merge.
|
|
*/
|
|
|
|
module.exports = function mergeOptions (parent, child, vm) {
|
|
guardComponents(child.components)
|
|
var options = {}
|
|
var key
|
|
for (key in parent) {
|
|
merge(parent[key], child[key], key)
|
|
}
|
|
for (key in child) {
|
|
if (!(parent.hasOwnProperty(key))) {
|
|
merge(parent[key], child[key], key)
|
|
}
|
|
}
|
|
var mixins = child.mixins
|
|
if (mixins) {
|
|
for (var i = 0, l = mixins.length; i < l; i++) {
|
|
for (key in mixins[i]) {
|
|
merge(options[key], mixins[i][key], key)
|
|
}
|
|
}
|
|
}
|
|
function merge (parentVal, childVal, key) {
|
|
var strat = strats[key] || defaultStrat
|
|
options[key] = strat(parentVal, childVal, vm, key)
|
|
}
|
|
return options
|
|
}
|
|
|
|
/***/ },
|
|
/* 20 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.exports = {
|
|
|
|
/**
|
|
* The prefix to look for when parsing directives.
|
|
*
|
|
* @type {String}
|
|
*/
|
|
|
|
prefix: 'v-',
|
|
|
|
/**
|
|
* Whether to print debug messages.
|
|
* Also enables stack trace for warnings.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
|
|
debug: false,
|
|
|
|
/**
|
|
* Whether to suppress warnings.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
|
|
silent: false,
|
|
|
|
/**
|
|
* Whether allow observer to alter data objects'
|
|
* __proto__.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
|
|
proto: true,
|
|
|
|
/**
|
|
* Whether to parse mustache tags in templates.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
|
|
interpolate: true,
|
|
|
|
/**
|
|
* Whether to use async rendering.
|
|
*/
|
|
|
|
async: true,
|
|
|
|
/**
|
|
* Internal flag to indicate the delimiters have been
|
|
* changed.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
|
|
_delimitersChanged: true
|
|
|
|
}
|
|
|
|
/**
|
|
* Interpolation delimiters.
|
|
* We need to mark the changed flag so that the text parser
|
|
* knows it needs to recompile the regex.
|
|
*
|
|
* @type {Array<String>}
|
|
*/
|
|
|
|
var delimiters = ['{{', '}}']
|
|
Object.defineProperty(module.exports, 'delimiters', {
|
|
get: function () {
|
|
return delimiters
|
|
},
|
|
set: function (val) {
|
|
delimiters = val
|
|
this._delimitersChanged = true
|
|
}
|
|
})
|
|
|
|
/***/ },
|
|
/* 21 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var config = __webpack_require__(20)
|
|
var Observer = __webpack_require__(49)
|
|
var expParser = __webpack_require__(44)
|
|
var Batcher = __webpack_require__(50)
|
|
|
|
var batcher = new Batcher()
|
|
var uid = 0
|
|
|
|
/**
|
|
* A watcher parses an expression, collects dependencies,
|
|
* and fires callback when the expression value changes.
|
|
* This is used for both the $watch() api and directives.
|
|
*
|
|
* @param {Vue} vm
|
|
* @param {String} expression
|
|
* @param {Function} cb
|
|
* @param {Array} [filters]
|
|
* @param {Boolean} [needSet]
|
|
* @param {Boolean} [deep]
|
|
* @constructor
|
|
*/
|
|
|
|
function Watcher (vm, expression, cb, filters, needSet, deep) {
|
|
this.vm = vm
|
|
vm._watcherList.push(this)
|
|
this.expression = expression
|
|
this.cbs = [cb]
|
|
this.id = ++uid // uid for batching
|
|
this.active = true
|
|
this.deep = deep
|
|
this.deps = Object.create(null)
|
|
// setup filters if any.
|
|
// We delegate directive filters here to the watcher
|
|
// because they need to be included in the dependency
|
|
// collection process.
|
|
this.readFilters = filters && filters.read
|
|
this.writeFilters = filters && filters.write
|
|
// parse expression for getter/setter
|
|
var res = expParser.parse(expression, needSet)
|
|
this.getter = res.get
|
|
this.setter = res.set
|
|
this.value = this.get()
|
|
}
|
|
|
|
var p = Watcher.prototype
|
|
|
|
/**
|
|
* Add a binding dependency to this directive.
|
|
*
|
|
* @param {Binding} binding
|
|
*/
|
|
|
|
p.addDep = function (binding) {
|
|
var id = binding.id
|
|
if (!this.newDeps[id]) {
|
|
this.newDeps[id] = binding
|
|
if (!this.deps[id]) {
|
|
this.deps[id] = binding
|
|
binding.addSub(this)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Evaluate the getter, and re-collect dependencies.
|
|
*/
|
|
|
|
p.get = function () {
|
|
this.beforeGet()
|
|
var vm = this.vm
|
|
var value
|
|
try {
|
|
value = this.getter.call(vm, vm)
|
|
} catch (e) {}
|
|
// use JSON.stringify to "touch" every property
|
|
// so they are all tracked as dependencies for
|
|
// deep watching
|
|
if (this.deep) JSON.stringify(value)
|
|
value = _.applyFilters(value, this.readFilters, vm)
|
|
this.afterGet()
|
|
return value
|
|
}
|
|
|
|
/**
|
|
* Set the corresponding value with the setter.
|
|
*
|
|
* @param {*} value
|
|
*/
|
|
|
|
p.set = function (value) {
|
|
var vm = this.vm
|
|
value = _.applyFilters(
|
|
value, this.writeFilters, vm, this.value
|
|
)
|
|
try {
|
|
this.setter.call(vm, vm, value)
|
|
} catch (e) {}
|
|
}
|
|
|
|
/**
|
|
* Prepare for dependency collection.
|
|
*/
|
|
|
|
p.beforeGet = function () {
|
|
Observer.target = this
|
|
this.newDeps = {}
|
|
}
|
|
|
|
/**
|
|
* Clean up for dependency collection.
|
|
*/
|
|
|
|
p.afterGet = function () {
|
|
Observer.target = null
|
|
for (var id in this.deps) {
|
|
if (!this.newDeps[id]) {
|
|
this.deps[id].removeSub(this)
|
|
}
|
|
}
|
|
this.deps = this.newDeps
|
|
}
|
|
|
|
/**
|
|
* Subscriber interface.
|
|
* Will be called when a dependency changes.
|
|
*/
|
|
|
|
p.update = function () {
|
|
if (config.async) {
|
|
batcher.push(this)
|
|
} else {
|
|
this.run()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Batcher job interface.
|
|
* Will be called by the batcher.
|
|
*/
|
|
|
|
p.run = function () {
|
|
if (this.active) {
|
|
var value = this.get()
|
|
if (
|
|
(typeof value === 'object' && value !== null) ||
|
|
value !== this.value
|
|
) {
|
|
var oldValue = this.value
|
|
this.value = value
|
|
var cbs = this.cbs
|
|
for (var i = 0, l = cbs.length; i < l; i++) {
|
|
cbs[i](value, oldValue)
|
|
// if a callback also removed other callbacks,
|
|
// we need to adjust the loop accordingly.
|
|
var removed = l - cbs.length
|
|
if (removed) {
|
|
i -= removed
|
|
l -= removed
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a callback.
|
|
*
|
|
* @param {Function} cb
|
|
*/
|
|
|
|
p.addCb = function (cb) {
|
|
this.cbs.push(cb)
|
|
}
|
|
|
|
/**
|
|
* Remove a callback.
|
|
*
|
|
* @param {Function} cb
|
|
*/
|
|
|
|
p.removeCb = function (cb) {
|
|
var cbs = this.cbs
|
|
if (cbs.length > 1) {
|
|
var i = cbs.indexOf(cb)
|
|
if (i > -1) {
|
|
cbs.splice(i, 1)
|
|
}
|
|
} else if (cb === cbs[0]) {
|
|
this.teardown()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove self from all dependencies' subcriber list.
|
|
*/
|
|
|
|
p.teardown = function () {
|
|
if (this.active) {
|
|
// remove self from vm's watcher list
|
|
// we can skip this if the vm if being destroyed
|
|
// which can improve teardown performance.
|
|
if (!this.vm._isBeingDestroyed) {
|
|
var list = this.vm._watcherList
|
|
list.splice(list.indexOf(this))
|
|
}
|
|
for (var id in this.deps) {
|
|
this.deps[id].removeSub(this)
|
|
}
|
|
this.active = false
|
|
this.vm = this.cbs = this.value = null
|
|
}
|
|
}
|
|
|
|
module.exports = Watcher
|
|
|
|
/***/ },
|
|
/* 22 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
|
|
module.exports = {
|
|
|
|
bind: function () {
|
|
this.attr = this.el.nodeType === 3
|
|
? 'nodeValue'
|
|
: 'textContent'
|
|
},
|
|
|
|
update: function (value) {
|
|
this.el[this.attr] = _.toString(value)
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 23 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var templateParser = __webpack_require__(51)
|
|
|
|
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 = _.toString(value)
|
|
if (this.nodes) {
|
|
this.swap(value)
|
|
} else {
|
|
this.el.innerHTML = value
|
|
}
|
|
},
|
|
|
|
swap: function (value) {
|
|
// remove old nodes
|
|
var i = this.nodes.length
|
|
while (i--) {
|
|
_.remove(this.nodes[i])
|
|
}
|
|
// convert new value to a fragment
|
|
var frag = templateParser.parse(value, true)
|
|
// save a reference to these nodes so we can remove later
|
|
this.nodes = _.toArray(frag.childNodes)
|
|
_.before(frag, this.el)
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 24 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
// xlink
|
|
var xlinkNS = 'http://www.w3.org/1999/xlink'
|
|
var xlinkRE = /^xlink:/
|
|
|
|
module.exports = {
|
|
|
|
priority: 850,
|
|
|
|
bind: function () {
|
|
var name = this.arg
|
|
this.update = xlinkRE.test(name)
|
|
? xlinkHandler
|
|
: defaultHandler
|
|
}
|
|
|
|
}
|
|
|
|
function defaultHandler (value) {
|
|
if (value || value === 0) {
|
|
this.el.setAttribute(this.arg, value)
|
|
} else {
|
|
this.el.removeAttribute(this.arg)
|
|
}
|
|
}
|
|
|
|
function xlinkHandler (value) {
|
|
if (value != null) {
|
|
this.el.setAttributeNS(xlinkNS, this.arg, value)
|
|
} else {
|
|
this.el.removeAttributeNS(xlinkNS, 'href')
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 25 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var transition = __webpack_require__(45)
|
|
|
|
module.exports = function (value) {
|
|
var el = this.el
|
|
transition.apply(el, value ? 1 : -1, function () {
|
|
el.style.display = value ? '' : 'none'
|
|
}, this.vm)
|
|
}
|
|
|
|
/***/ },
|
|
/* 26 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var addClass = _.addClass
|
|
var removeClass = _.removeClass
|
|
|
|
module.exports = function (value) {
|
|
if (this.arg) {
|
|
var method = value ? addClass : removeClass
|
|
method(this.el, this.arg)
|
|
} else {
|
|
if (this.lastVal) {
|
|
removeClass(this.el, this.lastVal)
|
|
}
|
|
if (value) {
|
|
addClass(this.el, value)
|
|
this.lastVal = value
|
|
}
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 27 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.exports = {
|
|
|
|
isLiteral: true,
|
|
|
|
bind: function () {
|
|
this.vm.$$[this.expression] = this.el
|
|
},
|
|
|
|
unbind: function () {
|
|
delete this.vm.$$[this.expression]
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 28 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
|
|
module.exports = {
|
|
|
|
isLiteral: true,
|
|
|
|
bind: function () {
|
|
if (this.el !== this.vm.$el) {
|
|
_.warn(
|
|
'v-ref should only be used on instance root nodes.'
|
|
)
|
|
return
|
|
}
|
|
this.owner = this.vm.$parent
|
|
this.owner.$[this.expression] = this.vm
|
|
},
|
|
|
|
unbind: function () {
|
|
if (this.owner.$[this.expression] === this.vm) {
|
|
delete this.owner.$[this.expression]
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 29 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var config = __webpack_require__(20)
|
|
|
|
module.exports = {
|
|
|
|
bind: function () {
|
|
var el = this.el
|
|
this.vm.$once('hook:compiled', function () {
|
|
el.removeAttribute(config.prefix + 'cloak')
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 30 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var prefixes = ['-webkit-', '-moz-', '-ms-']
|
|
var importantRE = /!important;?$/
|
|
|
|
module.exports = {
|
|
|
|
bind: function () {
|
|
var prop = this.arg
|
|
if (!prop) return
|
|
if (prop.charAt(0) === '$') {
|
|
// properties that start with $ will be auto-prefixed
|
|
prop = prop.slice(1)
|
|
this.prefixed = true
|
|
}
|
|
this.prop = prop
|
|
},
|
|
|
|
update: function (value) {
|
|
var prop = this.prop
|
|
// cast possible numbers/booleans into strings
|
|
if (value != null) {
|
|
value += ''
|
|
}
|
|
if (prop) {
|
|
var isImportant = importantRE.test(value)
|
|
? 'important'
|
|
: ''
|
|
if (isImportant) {
|
|
value = value.replace(importantRE, '').trim()
|
|
}
|
|
this.el.style.setProperty(prop, value, isImportant)
|
|
if (this.prefixed) {
|
|
var i = prefixes.length
|
|
while (i--) {
|
|
this.el.style.setProperty(
|
|
prefixes[i] + prop,
|
|
value,
|
|
isImportant
|
|
)
|
|
}
|
|
}
|
|
} else {
|
|
this.el.style.cssText = value
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 31 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var templateParser = __webpack_require__(51)
|
|
var transition = __webpack_require__(45)
|
|
|
|
module.exports = {
|
|
|
|
isLiteral: true,
|
|
|
|
bind: function () {
|
|
var el = this.el
|
|
this.start = document.createComment('v-partial-start')
|
|
this.end = document.createComment('v-partial-end')
|
|
if (el.nodeType !== 8) {
|
|
el.innerHTML = ''
|
|
}
|
|
if (el.tagName === 'TEMPLATE' || el.nodeType === 8) {
|
|
_.replace(el, this.end)
|
|
} else {
|
|
el.appendChild(this.end)
|
|
}
|
|
_.before(this.start, this.end)
|
|
if (!this._isDynamicLiteral) {
|
|
this.compile(this.expression)
|
|
}
|
|
},
|
|
|
|
update: function (id) {
|
|
this.teardown()
|
|
this.compile(id)
|
|
},
|
|
|
|
compile: function (id) {
|
|
var partial = this.vm.$options.partials[id]
|
|
_.assertAsset(partial, 'partial', id)
|
|
if (!partial) {
|
|
return
|
|
}
|
|
var vm = this.vm
|
|
var frag = templateParser.parse(partial, true)
|
|
var decompile = vm.$compile(frag)
|
|
this.decompile = function () {
|
|
decompile()
|
|
transition.blockRemove(this.start, this.end, vm)
|
|
}
|
|
transition.blockAppend(frag, this.end, vm)
|
|
},
|
|
|
|
teardown: function () {
|
|
if (this.decompile) {
|
|
this.decompile()
|
|
this.decompile = null
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 32 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.exports = {
|
|
|
|
priority: 1000,
|
|
isLiteral: true,
|
|
|
|
bind: function () {
|
|
this.el.__v_trans = {
|
|
id: this.expression
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 33 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
|
|
module.exports = {
|
|
|
|
acceptStatement: true,
|
|
priority: 700,
|
|
|
|
bind: function () {
|
|
// deal with iframes
|
|
if (
|
|
this.el.tagName === 'IFRAME' &&
|
|
this.arg !== 'load'
|
|
) {
|
|
var self = this
|
|
this.iframeBind = function () {
|
|
_.on(self.el.contentWindow, self.arg, self.handler)
|
|
}
|
|
_.on(this.el, 'load', this.iframeBind)
|
|
}
|
|
},
|
|
|
|
update: function (handler) {
|
|
if (typeof handler !== 'function') {
|
|
_.warn(
|
|
'Directive "v-on:' + this.expression + '" ' +
|
|
'expects a function value.'
|
|
)
|
|
return
|
|
}
|
|
this.reset()
|
|
var vm = this.vm
|
|
this.handler = function (e) {
|
|
e.targetVM = vm
|
|
vm.$event = e
|
|
var res = handler(e)
|
|
vm.$event = null
|
|
return res
|
|
}
|
|
if (this.iframeBind) {
|
|
this.iframeBind()
|
|
} else {
|
|
_.on(this.el, this.arg, this.handler)
|
|
}
|
|
},
|
|
|
|
reset: function () {
|
|
var el = this.iframeBind
|
|
? this.el.contentWindow
|
|
: this.el
|
|
if (this.handler) {
|
|
_.off(el, this.arg, this.handler)
|
|
}
|
|
},
|
|
|
|
unbind: function () {
|
|
this.reset()
|
|
_.off(this.el, 'load', this.iframeBind)
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 34 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var templateParser = __webpack_require__(51)
|
|
|
|
module.exports = {
|
|
|
|
isLiteral: true,
|
|
|
|
/**
|
|
* Setup. Two possible usages:
|
|
*
|
|
* - static:
|
|
* v-component="comp"
|
|
*
|
|
* - dynamic:
|
|
* v-component="{{currentView}}"
|
|
*/
|
|
|
|
bind: function () {
|
|
if (!this.el.__vue__) {
|
|
// create a ref anchor
|
|
this.ref = document.createComment('v-component')
|
|
_.replace(this.el, this.ref)
|
|
// check keep-alive options
|
|
this.checkKeepAlive()
|
|
// check parent directives
|
|
this.parentLinker = this.el._parentLinker
|
|
// if static, build right now.
|
|
if (!this._isDynamicLiteral) {
|
|
this.resolveCtor(this.expression)
|
|
this.build()
|
|
}
|
|
} else {
|
|
_.warn(
|
|
'v-component="' + this.expression + '" cannot be ' +
|
|
'used on an already mounted instance.'
|
|
)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Check if the "keep-alive" flag is present.
|
|
* If yes, instead of destroying the active vm when
|
|
* hiding (v-if) or switching (dynamic literal) it,
|
|
* we simply remove it from the DOM and save it in a
|
|
* cache object, with its constructor id as the key.
|
|
*/
|
|
|
|
checkKeepAlive: function () {
|
|
// check keep-alive flag
|
|
this.keepAlive = this.el.hasAttribute('keep-alive')
|
|
if (this.keepAlive) {
|
|
this.el.removeAttribute('keep-alive')
|
|
this.cache = {}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Resolve the component constructor to use when creating
|
|
* the child vm.
|
|
*/
|
|
|
|
resolveCtor: function (id) {
|
|
this.ctorId = id
|
|
this.Ctor = this.vm.$options.components[id]
|
|
_.assertAsset(this.Ctor, 'component', id)
|
|
},
|
|
|
|
/**
|
|
* Instantiate/insert a new child vm.
|
|
* If keep alive and has cached instance, insert that
|
|
* instance; otherwise build a new one and cache it.
|
|
*/
|
|
|
|
build: function () {
|
|
if (this.keepAlive) {
|
|
var cached = this.cache[this.ctorId]
|
|
if (cached) {
|
|
this.childVM = cached
|
|
cached.$before(this.ref)
|
|
return
|
|
}
|
|
}
|
|
var vm = this.vm
|
|
if (this.Ctor && !this.childVM) {
|
|
this.childVM = vm.$addChild({
|
|
el: templateParser.clone(this.el)
|
|
}, this.Ctor)
|
|
if (this.parentLinker) {
|
|
var dirCount = vm._directives.length
|
|
var targetVM = this.childVM.$options.inherit
|
|
? this.childVM
|
|
: vm
|
|
this.parentLinker(targetVM, this.childVM.$el)
|
|
this.parentDirs = vm._directives.slice(dirCount)
|
|
}
|
|
if (this.keepAlive) {
|
|
this.cache[this.ctorId] = this.childVM
|
|
}
|
|
this.childVM.$before(this.ref)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Teardown the active vm.
|
|
* If keep alive, simply remove it; otherwise destroy it.
|
|
*
|
|
* @param {Boolean} remove
|
|
*/
|
|
|
|
unbuild: function (remove) {
|
|
var child = this.childVM
|
|
if (!child) {
|
|
return
|
|
}
|
|
if (this.keepAlive) {
|
|
if (remove) {
|
|
child.$remove()
|
|
}
|
|
} else {
|
|
child.$destroy(remove)
|
|
var parentDirs = this.parentDirs
|
|
if (parentDirs) {
|
|
var i = parentDirs.length
|
|
while (i--) {
|
|
parentDirs[i]._teardown()
|
|
}
|
|
}
|
|
}
|
|
this.childVM = null
|
|
},
|
|
|
|
/**
|
|
* Update callback for the dynamic literal scenario,
|
|
* e.g. v-component="{{view}}"
|
|
*/
|
|
|
|
update: function (value) {
|
|
this.unbuild(true)
|
|
if (value) {
|
|
this.resolveCtor(value)
|
|
this.build()
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Unbind.
|
|
* Make sure keepAlive is set to false so that the
|
|
* instance is always destroyed.
|
|
*/
|
|
|
|
unbind: function () {
|
|
this.keepAlive = false
|
|
this.unbuild()
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 35 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var isObject = _.isObject
|
|
var textParser = __webpack_require__(42)
|
|
var expParser = __webpack_require__(44)
|
|
var templateParser = __webpack_require__(51)
|
|
var compile = __webpack_require__(46)
|
|
var transclude = __webpack_require__(47)
|
|
var mergeOptions = __webpack_require__(19)
|
|
var uid = 0
|
|
|
|
module.exports = {
|
|
|
|
/**
|
|
* Setup.
|
|
*/
|
|
|
|
bind: function () {
|
|
// uid as a cache identifier
|
|
this.id = '__v_repeat_' + (++uid)
|
|
// we need to insert the objToArray converter
|
|
// as the first read filter.
|
|
if (!this.filters) {
|
|
this.filters = {}
|
|
}
|
|
// add the object -> array convert filter
|
|
var objectConverter = _.bind(objToArray, this)
|
|
if (!this.filters.read) {
|
|
this.filters.read = [objectConverter]
|
|
} else {
|
|
this.filters.read.unshift(objectConverter)
|
|
}
|
|
// setup ref node
|
|
this.ref = document.createComment('v-repeat')
|
|
_.replace(this.el, this.ref)
|
|
// check if this is a block repeat
|
|
this.template = this.el.tagName === 'TEMPLATE'
|
|
? templateParser.parse(this.el, true)
|
|
: this.el
|
|
// check other directives that need to be handled
|
|
// at v-repeat level
|
|
this.checkIf()
|
|
this.checkRef()
|
|
this.checkTrackById()
|
|
this.checkComponent()
|
|
// cache for primitive value instances
|
|
this.cache = Object.create(null)
|
|
},
|
|
|
|
/**
|
|
* Warn against v-if usage.
|
|
*/
|
|
|
|
checkIf: function () {
|
|
if (_.attr(this.el, 'if') !== null) {
|
|
_.warn(
|
|
'Don\'t use v-if with v-repeat. ' +
|
|
'Use v-show or the "filterBy" filter instead.'
|
|
)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Check if v-ref/ v-el is also present.
|
|
*/
|
|
|
|
checkRef: function () {
|
|
var childId = _.attr(this.el, 'ref')
|
|
this.childId = childId
|
|
? this.vm.$interpolate(childId)
|
|
: null
|
|
var elId = _.attr(this.el, 'el')
|
|
this.elId = elId
|
|
? this.vm.$interpolate(elId)
|
|
: null
|
|
},
|
|
|
|
/**
|
|
* Check for a track-by ID, which allows us to identify
|
|
* a piece of data and its associated instance by its
|
|
* unique id.
|
|
*/
|
|
|
|
checkTrackById: function () {
|
|
this.idKey = this.el.getAttribute('trackby')
|
|
if (this.idKey !== null) {
|
|
this.el.removeAttribute('trackby')
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Check the component constructor to use for repeated
|
|
* instances. If static we resolve it now, otherwise it
|
|
* needs to be resolved at build time with actual data.
|
|
*/
|
|
|
|
checkComponent: function () {
|
|
var id = _.attr(this.el, 'component')
|
|
var options = this.vm.$options
|
|
if (!id) {
|
|
this.Ctor = _.Vue // default constructor
|
|
this.inherit = true // inline repeats should inherit
|
|
// important: transclude with no options, just
|
|
// to ensure block start and block end
|
|
this.template = transclude(this.template)
|
|
this._linker = compile(this.template, options)
|
|
} else {
|
|
var tokens = textParser.parse(id)
|
|
if (!tokens) { // static component
|
|
var Ctor = this.Ctor = options.components[id]
|
|
_.assertAsset(Ctor, 'component', id)
|
|
if (Ctor) {
|
|
// merge an empty object with owner vm as parent
|
|
// so child vms can access parent assets.
|
|
var merged = mergeOptions(
|
|
Ctor.options,
|
|
{},
|
|
{ $parent: this.vm }
|
|
)
|
|
this.template = transclude(this.template, merged)
|
|
this._linker = compile(this.template, merged)
|
|
}
|
|
} else {
|
|
// to be resolved later
|
|
var ctorExp = textParser.tokensToExp(tokens)
|
|
this.ctorGetter = expParser.parse(ctorExp).get
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Update.
|
|
* This is called whenever the Array mutates.
|
|
*
|
|
* @param {Array} data
|
|
*/
|
|
|
|
update: function (data) {
|
|
if (typeof data === 'number') {
|
|
data = range(data)
|
|
}
|
|
this.vms = this.diff(data || [], this.vms)
|
|
// update v-ref
|
|
if (this.childId) {
|
|
this.vm.$[this.childId] = this.vms
|
|
}
|
|
if (this.elId) {
|
|
this.vm.$$[this.elId] = this.vms.map(function (vm) {
|
|
return vm.$el
|
|
})
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Diff, based on new data and old data, determine the
|
|
* minimum amount of DOM manipulations needed to make the
|
|
* DOM reflect the new data Array.
|
|
*
|
|
* The algorithm diffs the new data Array by storing a
|
|
* hidden reference to an owner vm instance on previously
|
|
* seen data. This allows us to achieve O(n) which is
|
|
* better than a levenshtein distance based algorithm,
|
|
* which is O(m * n).
|
|
*
|
|
* @param {Array} data
|
|
* @param {Array} oldVms
|
|
* @return {Array}
|
|
*/
|
|
|
|
diff: function (data, oldVms) {
|
|
var idKey = this.idKey
|
|
var converted = this.converted
|
|
var ref = this.ref
|
|
var alias = this.arg
|
|
var init = !oldVms
|
|
var vms = new Array(data.length)
|
|
var obj, raw, vm, i, l
|
|
// First pass, go through the new Array and fill up
|
|
// the new vms array. If a piece of data has a cached
|
|
// instance for it, we reuse it. Otherwise build a new
|
|
// instance.
|
|
for (i = 0, l = data.length; i < l; i++) {
|
|
obj = data[i]
|
|
raw = converted ? obj.value : obj
|
|
vm = !init && this.getVm(raw)
|
|
if (vm) { // reusable instance
|
|
vm._reused = true
|
|
vm.$index = i // update $index
|
|
if (converted) {
|
|
vm.$key = obj.key // update $key
|
|
}
|
|
if (idKey) { // swap track by id data
|
|
if (alias) {
|
|
vm[alias] = raw
|
|
} else {
|
|
vm._setData(raw)
|
|
}
|
|
}
|
|
} else { // new instance
|
|
vm = this.build(obj, i)
|
|
vm._new = true
|
|
}
|
|
vms[i] = vm
|
|
// insert if this is first run
|
|
if (init) {
|
|
vm.$before(ref)
|
|
}
|
|
}
|
|
// if this is the first run, we're done.
|
|
if (init) {
|
|
return vms
|
|
}
|
|
// Second pass, go through the old vm instances and
|
|
// destroy those who are not reused (and remove them
|
|
// from cache)
|
|
for (i = 0, l = oldVms.length; i < l; i++) {
|
|
vm = oldVms[i]
|
|
if (!vm._reused) {
|
|
this.uncacheVm(vm)
|
|
vm.$destroy(true)
|
|
}
|
|
}
|
|
// final pass, move/insert new instances into the
|
|
// right place. We're going in reverse here because
|
|
// insertBefore relies on the next sibling to be
|
|
// resolved.
|
|
var targetNext, currentNext
|
|
i = vms.length
|
|
while (i--) {
|
|
vm = vms[i]
|
|
// this is the vm that we should be in front of
|
|
targetNext = vms[i + 1]
|
|
if (!targetNext) {
|
|
// This is the last item. If it's reused then
|
|
// everything else will eventually be in the right
|
|
// place, so no need to touch it. Otherwise, insert
|
|
// it.
|
|
if (!vm._reused) {
|
|
vm.$before(ref)
|
|
}
|
|
} else {
|
|
if (vm._reused) {
|
|
// this is the vm we are actually in front of
|
|
currentNext = findNextVm(vm, ref)
|
|
// we only need to move if we are not in the right
|
|
// place already.
|
|
if (currentNext !== targetNext) {
|
|
vm.$before(targetNext.$el, null, false)
|
|
}
|
|
} else {
|
|
// new instance, insert to existing next
|
|
vm.$before(targetNext.$el)
|
|
}
|
|
}
|
|
vm._new = false
|
|
vm._reused = false
|
|
}
|
|
return vms
|
|
},
|
|
|
|
/**
|
|
* Build a new instance and cache it.
|
|
*
|
|
* @param {Object} data
|
|
* @param {Number} index
|
|
*/
|
|
|
|
build: function (data, index) {
|
|
var original = data
|
|
var meta = { $index: index }
|
|
if (this.converted) {
|
|
meta.$key = original.key
|
|
}
|
|
var raw = this.converted ? data.value : data
|
|
var alias = this.arg
|
|
var hasAlias = !isObject(raw) || alias
|
|
// wrap the raw data with alias
|
|
data = hasAlias ? {} : raw
|
|
if (alias) {
|
|
data[alias] = raw
|
|
} else if (hasAlias) {
|
|
meta.$value = raw
|
|
}
|
|
// resolve constructor
|
|
var Ctor = this.Ctor || this.resolveCtor(data, meta)
|
|
var vm = this.vm.$addChild({
|
|
el: templateParser.clone(this.template),
|
|
_linker: this._linker,
|
|
_meta: meta,
|
|
data: data,
|
|
inherit: this.inherit
|
|
}, Ctor)
|
|
// cache instance
|
|
this.cacheVm(raw, vm)
|
|
return vm
|
|
},
|
|
|
|
/**
|
|
* Resolve a contructor to use for an instance.
|
|
* The tricky part here is that there could be dynamic
|
|
* components depending on instance data.
|
|
*
|
|
* @param {Object} data
|
|
* @param {Object} meta
|
|
* @return {Function}
|
|
*/
|
|
|
|
resolveCtor: function (data, meta) {
|
|
// create a temporary context object and copy data
|
|
// and meta properties onto it.
|
|
// use _.define to avoid accidentally overwriting scope
|
|
// properties.
|
|
var context = Object.create(this.vm)
|
|
var key
|
|
for (key in data) {
|
|
_.define(context, key, data[key])
|
|
}
|
|
for (key in meta) {
|
|
_.define(context, key, meta[key])
|
|
}
|
|
var id = this.ctorGetter.call(context, context)
|
|
var Ctor = this.vm.$options.components[id]
|
|
_.assertAsset(Ctor, 'component', id)
|
|
return Ctor
|
|
},
|
|
|
|
/**
|
|
* Unbind, teardown everything
|
|
*/
|
|
|
|
unbind: function () {
|
|
if (this.childId) {
|
|
delete this.vm.$[this.childId]
|
|
}
|
|
if (this.vms) {
|
|
var i = this.vms.length
|
|
var vm
|
|
while (i--) {
|
|
vm = this.vms[i]
|
|
this.uncacheVm(vm)
|
|
vm.$destroy()
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Cache a vm instance based on its data.
|
|
*
|
|
* If the data is an object, we save the vm's reference on
|
|
* the data object as a hidden property. Otherwise we
|
|
* cache them in an object and for each primitive value
|
|
* there is an array in case there are duplicates.
|
|
*
|
|
* @param {Object} data
|
|
* @param {Vue} vm
|
|
*/
|
|
|
|
cacheVm: function (data, vm) {
|
|
var idKey = this.idKey
|
|
var cache = this.cache
|
|
var id
|
|
if (idKey) {
|
|
id = data[idKey]
|
|
if (!cache[id]) {
|
|
cache[id] = vm
|
|
} else {
|
|
_.warn('Duplicate ID in v-repeat: ' + id)
|
|
}
|
|
} else if (isObject(data)) {
|
|
id = this.id
|
|
if (data.hasOwnProperty(id)) {
|
|
if (data[id] === null) {
|
|
data[id] = vm
|
|
} else {
|
|
_.warn(
|
|
'Duplicate objects are not supported in v-repeat.'
|
|
)
|
|
}
|
|
} else {
|
|
_.define(data, this.id, vm)
|
|
}
|
|
} else {
|
|
if (!cache[data]) {
|
|
cache[data] = [vm]
|
|
} else {
|
|
cache[data].push(vm)
|
|
}
|
|
}
|
|
vm._raw = data
|
|
},
|
|
|
|
/**
|
|
* Try to get a cached instance from a piece of data.
|
|
*
|
|
* @param {Object} data
|
|
* @return {Vue|undefined}
|
|
*/
|
|
|
|
getVm: function (data) {
|
|
if (this.idKey) {
|
|
return this.cache[data[this.idKey]]
|
|
} else if (isObject(data)) {
|
|
return data[this.id]
|
|
} else {
|
|
var cached = this.cache[data]
|
|
if (cached) {
|
|
var i = 0
|
|
var vm = cached[i]
|
|
// since duplicated vm instances might be a reused
|
|
// one OR a newly created one, we need to return the
|
|
// first instance that is neither of these.
|
|
while (vm && (vm._reused || vm._new)) {
|
|
vm = cached[++i]
|
|
}
|
|
return vm
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Delete a cached vm instance.
|
|
*
|
|
* @param {Vue} vm
|
|
*/
|
|
|
|
uncacheVm: function (vm) {
|
|
var data = vm._raw
|
|
if (this.idKey) {
|
|
this.cache[data[this.idKey]] = null
|
|
} else if (isObject(data)) {
|
|
data[this.id] = null
|
|
vm._raw = null
|
|
} else {
|
|
this.cache[data].pop()
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Helper to find the next element that is an instance
|
|
* root node. This is necessary because a destroyed vm's
|
|
* element could still be lingering in the DOM before its
|
|
* leaving transition finishes, but its __vue__ reference
|
|
* should have been removed so we can skip them.
|
|
*
|
|
* @param {Vue} vm
|
|
* @param {CommentNode} ref
|
|
* @return {Vue}
|
|
*/
|
|
|
|
function findNextVm (vm, ref) {
|
|
var el = (vm._blockEnd || vm.$el).nextSibling
|
|
while (!el.__vue__ && el !== ref) {
|
|
el = el.nextSibling
|
|
}
|
|
return el.__vue__
|
|
}
|
|
|
|
/**
|
|
* Attempt to convert non-Array objects to array.
|
|
* This is the default filter installed to every v-repeat
|
|
* directive.
|
|
*
|
|
* It will be called with **the directive** as `this`
|
|
* context so that we can mark the repeat array as converted
|
|
* from an object.
|
|
*
|
|
* @param {*} obj
|
|
* @return {Array}
|
|
* @private
|
|
*/
|
|
|
|
function objToArray (obj) {
|
|
if (!_.isPlainObject(obj)) {
|
|
return obj
|
|
}
|
|
var keys = Object.keys(obj)
|
|
var i = keys.length
|
|
var res = new Array(i)
|
|
var key
|
|
while (i--) {
|
|
key = keys[i]
|
|
res[i] = {
|
|
key: key,
|
|
value: obj[key]
|
|
}
|
|
}
|
|
// `this` points to the repeat directive instance
|
|
this.converted = true
|
|
return res
|
|
}
|
|
|
|
/**
|
|
* Create a range array from given number.
|
|
*
|
|
* @param {Number} n
|
|
* @return {Array}
|
|
*/
|
|
|
|
function range (n) {
|
|
var i = -1
|
|
var ret = new Array(n)
|
|
while (++i < n) {
|
|
ret[i] = i
|
|
}
|
|
return ret
|
|
}
|
|
|
|
/***/ },
|
|
/* 36 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var compile = __webpack_require__(46)
|
|
var templateParser = __webpack_require__(51)
|
|
var transition = __webpack_require__(45)
|
|
|
|
module.exports = {
|
|
|
|
bind: function () {
|
|
var el = this.el
|
|
if (!el.__vue__) {
|
|
this.start = document.createComment('v-if-start')
|
|
this.end = document.createComment('v-if-end')
|
|
_.replace(el, this.end)
|
|
_.before(this.start, this.end)
|
|
if (el.tagName === 'TEMPLATE') {
|
|
this.template = templateParser.parse(el, true)
|
|
} else {
|
|
this.template = document.createDocumentFragment()
|
|
this.template.appendChild(el)
|
|
}
|
|
// compile the nested partial
|
|
this.linker = compile(
|
|
this.template,
|
|
this.vm.$options,
|
|
true
|
|
)
|
|
} else {
|
|
this.invalid = true
|
|
_.warn(
|
|
'v-if="' + this.expression + '" cannot be ' +
|
|
'used on an already mounted instance.'
|
|
)
|
|
}
|
|
},
|
|
|
|
update: function (value) {
|
|
if (this.invalid) return
|
|
if (value) {
|
|
this.insert()
|
|
} else {
|
|
this.teardown()
|
|
}
|
|
},
|
|
|
|
insert: function () {
|
|
// avoid duplicate inserts, since update() can be
|
|
// called with different truthy values
|
|
if (this.decompile) {
|
|
return
|
|
}
|
|
var vm = this.vm
|
|
var frag = templateParser.clone(this.template)
|
|
var decompile = this.linker(vm, frag)
|
|
this.decompile = function () {
|
|
decompile()
|
|
transition.blockRemove(this.start, this.end, vm)
|
|
}
|
|
transition.blockAppend(frag, this.end, vm)
|
|
},
|
|
|
|
teardown: function () {
|
|
if (this.decompile) {
|
|
this.decompile()
|
|
this.decompile = null
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 37 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var Watcher = __webpack_require__(21)
|
|
|
|
module.exports = {
|
|
|
|
priority: 900,
|
|
|
|
bind: function () {
|
|
var vm = this.vm
|
|
if (this.el !== vm.$el) {
|
|
_.warn(
|
|
'v-with can only be used on instance root elements.'
|
|
)
|
|
} else if (!vm.$parent) {
|
|
_.warn(
|
|
'v-with must be used on an instance with a parent.'
|
|
)
|
|
} else {
|
|
var key = this.arg
|
|
this.watcher = new Watcher(
|
|
vm.$parent,
|
|
this.expression,
|
|
key
|
|
? function (val) {
|
|
vm.$set(key, val)
|
|
}
|
|
: function (val) {
|
|
vm.$data = val
|
|
}
|
|
)
|
|
// initial set
|
|
var initialVal = this.watcher.value
|
|
if (key) {
|
|
vm.$set(key, initialVal)
|
|
} else {
|
|
vm.$data = initialVal
|
|
}
|
|
}
|
|
},
|
|
|
|
unbind: function () {
|
|
if (this.watcher) {
|
|
this.watcher.teardown()
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 38 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var Path = __webpack_require__(41)
|
|
|
|
/**
|
|
* Filter filter for v-repeat
|
|
*
|
|
* @param {String} searchKey
|
|
* @param {String} [delimiter]
|
|
* @param {String} dataKey
|
|
*/
|
|
|
|
exports.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))
|
|
return arr.filter(function (item) {
|
|
return dataKey
|
|
? contains(Path.get(item, dataKey), search)
|
|
: contains(item, search)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Filter filter for v-repeat
|
|
*
|
|
* @param {String} sortKey
|
|
* @param {String} reverseKey
|
|
*/
|
|
|
|
exports.orderBy = function (arr, sortKey, reverseKey) {
|
|
var key =
|
|
_.stripQuotes(sortKey) ||
|
|
this.$get(sortKey)
|
|
if (!key) {
|
|
return arr
|
|
}
|
|
var order = 1
|
|
if (reverseKey) {
|
|
if (reverseKey === '-1') {
|
|
order = -1
|
|
} else if (reverseKey.charCodeAt(0) === 0x21) { // !
|
|
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 = Path.get(a, key)
|
|
b = Path.get(b, key)
|
|
return a === b ? 0 : a > b ? order : -order
|
|
})
|
|
}
|
|
|
|
/**
|
|
* String contain helper
|
|
*
|
|
* @param {*} val
|
|
* @param {String} search
|
|
*/
|
|
|
|
function contains (val, search) {
|
|
if (_.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
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 39 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var uid = 0
|
|
|
|
/**
|
|
* A binding is an observable that can have multiple
|
|
* directives subscribing to it.
|
|
*
|
|
* @constructor
|
|
*/
|
|
|
|
function Binding () {
|
|
this.id = ++uid
|
|
this.subs = []
|
|
}
|
|
|
|
var p = Binding.prototype
|
|
|
|
/**
|
|
* Add a directive subscriber.
|
|
*
|
|
* @param {Directive} sub
|
|
*/
|
|
|
|
p.addSub = function (sub) {
|
|
this.subs.push(sub)
|
|
}
|
|
|
|
/**
|
|
* Remove a directive subscriber.
|
|
*
|
|
* @param {Directive} sub
|
|
*/
|
|
|
|
p.removeSub = function (sub) {
|
|
if (this.subs.length) {
|
|
var i = this.subs.indexOf(sub)
|
|
if (i > -1) this.subs.splice(i, 1)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notify all subscribers of a new value.
|
|
*/
|
|
|
|
p.notify = function () {
|
|
for (var i = 0, l = this.subs.length; i < l; i++) {
|
|
this.subs[i].update()
|
|
}
|
|
}
|
|
|
|
module.exports = Binding
|
|
|
|
/***/ },
|
|
/* 40 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var config = __webpack_require__(20)
|
|
var Watcher = __webpack_require__(21)
|
|
var textParser = __webpack_require__(42)
|
|
var expParser = __webpack_require__(44)
|
|
|
|
/**
|
|
* A directive links a DOM element with a piece of data,
|
|
* which is the result of evaluating an expression.
|
|
* It registers a watcher with the expression and calls
|
|
* the DOM update function when a change is triggered.
|
|
*
|
|
* @param {String} name
|
|
* @param {Node} el
|
|
* @param {Vue} vm
|
|
* @param {Object} descriptor
|
|
* - {String} expression
|
|
* - {String} [arg]
|
|
* - {Array<Object>} [filters]
|
|
* @param {Object} def - directive definition object
|
|
* @param {Function} [linker] - pre-compiled linker function
|
|
* @constructor
|
|
*/
|
|
|
|
function Directive (name, el, vm, descriptor, def, linker) {
|
|
// public
|
|
this.name = name
|
|
this.el = el
|
|
this.vm = vm
|
|
// copy descriptor props
|
|
this.raw = descriptor.raw
|
|
this.expression = descriptor.expression
|
|
this.arg = descriptor.arg
|
|
this.filters = _.resolveFilters(vm, descriptor.filters)
|
|
// private
|
|
this._linker = linker
|
|
this._locked = false
|
|
this._bound = false
|
|
// init
|
|
this._bind(def)
|
|
}
|
|
|
|
var p = Directive.prototype
|
|
|
|
/**
|
|
* Initialize the directive, mixin definition properties,
|
|
* setup the watcher, call definition bind() and update()
|
|
* if present.
|
|
*
|
|
* @param {Object} def
|
|
*/
|
|
|
|
p._bind = function (def) {
|
|
if (this.name !== 'cloak' && this.el.removeAttribute) {
|
|
this.el.removeAttribute(config.prefix + this.name)
|
|
}
|
|
if (typeof def === 'function') {
|
|
this.update = def
|
|
} else {
|
|
_.extend(this, def)
|
|
}
|
|
this._watcherExp = this.expression
|
|
this._checkDynamicLiteral()
|
|
if (this.bind) {
|
|
this.bind()
|
|
}
|
|
if (
|
|
this.update && this._watcherExp &&
|
|
(!this.isLiteral || this._isDynamicLiteral) &&
|
|
!this._checkStatement()
|
|
) {
|
|
// use raw expression as identifier because filters
|
|
// make them different watchers
|
|
var watcher = this.vm._watchers[this.raw]
|
|
// wrapped updater for context
|
|
var dir = this
|
|
var update = this._update = function (val, oldVal) {
|
|
if (!dir._locked) {
|
|
dir.update(val, oldVal)
|
|
}
|
|
}
|
|
if (!watcher) {
|
|
watcher = this.vm._watchers[this.raw] = new Watcher(
|
|
this.vm,
|
|
this._watcherExp,
|
|
update, // callback
|
|
this.filters,
|
|
this.twoWay // need setter
|
|
)
|
|
} else {
|
|
watcher.addCb(update)
|
|
}
|
|
this._watcher = watcher
|
|
if (this._initValue != null) {
|
|
watcher.set(this._initValue)
|
|
} else {
|
|
this.update(watcher.value)
|
|
}
|
|
}
|
|
this._bound = true
|
|
}
|
|
|
|
/**
|
|
* check if this is a dynamic literal binding.
|
|
*
|
|
* e.g. v-component="{{currentView}}"
|
|
*/
|
|
|
|
p._checkDynamicLiteral = function () {
|
|
var expression = this.expression
|
|
if (expression && this.isLiteral) {
|
|
var tokens = textParser.parse(expression)
|
|
if (tokens) {
|
|
var exp = textParser.tokensToExp(tokens)
|
|
this.expression = this.vm.$get(exp)
|
|
this._watcherExp = exp
|
|
this._isDynamicLiteral = true
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if the directive is a function caller
|
|
* and if the expression is a callable one. If both true,
|
|
* we wrap up the expression and use it as the event
|
|
* handler.
|
|
*
|
|
* e.g. v-on="click: a++"
|
|
*
|
|
* @return {Boolean}
|
|
*/
|
|
|
|
p._checkStatement = function () {
|
|
var expression = this.expression
|
|
if (
|
|
expression && this.acceptStatement &&
|
|
!expParser.pathTestRE.test(expression)
|
|
) {
|
|
var fn = expParser.parse(expression).get
|
|
var vm = this.vm
|
|
var handler = function () {
|
|
fn.call(vm, vm)
|
|
}
|
|
if (this.filters) {
|
|
handler = _.applyFilters(
|
|
handler,
|
|
this.filters.read,
|
|
vm
|
|
)
|
|
}
|
|
this.update(handler)
|
|
return true
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Teardown the watcher and call unbind.
|
|
*/
|
|
|
|
p._teardown = function () {
|
|
if (this._bound) {
|
|
if (this.unbind) {
|
|
this.unbind()
|
|
}
|
|
var watcher = this._watcher
|
|
if (watcher && watcher.active) {
|
|
watcher.removeCb(this._update)
|
|
if (!watcher.active) {
|
|
this.vm._watchers[this.raw] = null
|
|
}
|
|
}
|
|
this._bound = false
|
|
this.vm = this.el = this._watcher = null
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the corresponding value with the setter.
|
|
* This should only be used in two-way directives
|
|
* e.g. v-model.
|
|
*
|
|
* @param {*} value
|
|
* @param {Boolean} lock - prevent wrtie triggering update.
|
|
* @public
|
|
*/
|
|
|
|
p.set = function (value, lock) {
|
|
if (this.twoWay) {
|
|
if (lock) {
|
|
this._locked = true
|
|
}
|
|
this._watcher.set(value)
|
|
if (lock) {
|
|
var self = this
|
|
_.nextTick(function () {
|
|
self._locked = false
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = Directive
|
|
|
|
/***/ },
|
|
/* 41 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var Cache = __webpack_require__(52)
|
|
var pathCache = new Cache(1000)
|
|
var identRE = /^[$_a-zA-Z]+[\w$]*$/
|
|
|
|
/**
|
|
* Path-parsing algorithm scooped from Polymer/observe-js
|
|
*/
|
|
|
|
var pathStateMachine = {
|
|
'beforePath': {
|
|
'ws': ['beforePath'],
|
|
'ident': ['inIdent', 'append'],
|
|
'[': ['beforeElement'],
|
|
'eof': ['afterPath']
|
|
},
|
|
|
|
'inPath': {
|
|
'ws': ['inPath'],
|
|
'.': ['beforeIdent'],
|
|
'[': ['beforeElement'],
|
|
'eof': ['afterPath']
|
|
},
|
|
|
|
'beforeIdent': {
|
|
'ws': ['beforeIdent'],
|
|
'ident': ['inIdent', 'append']
|
|
},
|
|
|
|
'inIdent': {
|
|
'ident': ['inIdent', 'append'],
|
|
'0': ['inIdent', 'append'],
|
|
'number': ['inIdent', 'append'],
|
|
'ws': ['inPath', 'push'],
|
|
'.': ['beforeIdent', 'push'],
|
|
'[': ['beforeElement', 'push'],
|
|
'eof': ['afterPath', 'push']
|
|
},
|
|
|
|
'beforeElement': {
|
|
'ws': ['beforeElement'],
|
|
'0': ['afterZero', 'append'],
|
|
'number': ['inIndex', 'append'],
|
|
"'": ['inSingleQuote', 'append', ''],
|
|
'"': ['inDoubleQuote', 'append', '']
|
|
},
|
|
|
|
'afterZero': {
|
|
'ws': ['afterElement', 'push'],
|
|
']': ['inPath', 'push']
|
|
},
|
|
|
|
'inIndex': {
|
|
'0': ['inIndex', 'append'],
|
|
'number': ['inIndex', 'append'],
|
|
'ws': ['afterElement'],
|
|
']': ['inPath', 'push']
|
|
},
|
|
|
|
'inSingleQuote': {
|
|
"'": ['afterElement'],
|
|
'eof': 'error',
|
|
'else': ['inSingleQuote', 'append']
|
|
},
|
|
|
|
'inDoubleQuote': {
|
|
'"': ['afterElement'],
|
|
'eof': 'error',
|
|
'else': ['inDoubleQuote', 'append']
|
|
},
|
|
|
|
'afterElement': {
|
|
'ws': ['afterElement'],
|
|
']': ['inPath', 'push']
|
|
}
|
|
}
|
|
|
|
function noop () {}
|
|
|
|
/**
|
|
* Determine the type of a character in a keypath.
|
|
*
|
|
* @param {Char} char
|
|
* @return {String} type
|
|
*/
|
|
|
|
function getPathCharType (char) {
|
|
if (char === undefined) {
|
|
return 'eof'
|
|
}
|
|
|
|
var code = char.charCodeAt(0)
|
|
|
|
switch(code) {
|
|
case 0x5B: // [
|
|
case 0x5D: // ]
|
|
case 0x2E: // .
|
|
case 0x22: // "
|
|
case 0x27: // '
|
|
case 0x30: // 0
|
|
return char
|
|
|
|
case 0x5F: // _
|
|
case 0x24: // $
|
|
return 'ident'
|
|
|
|
case 0x20: // Space
|
|
case 0x09: // Tab
|
|
case 0x0A: // Newline
|
|
case 0x0D: // Return
|
|
case 0xA0: // No-break space
|
|
case 0xFEFF: // Byte Order Mark
|
|
case 0x2028: // Line Separator
|
|
case 0x2029: // Paragraph Separator
|
|
return 'ws'
|
|
}
|
|
|
|
// a-z, A-Z
|
|
if ((0x61 <= code && code <= 0x7A) ||
|
|
(0x41 <= code && code <= 0x5A)) {
|
|
return 'ident'
|
|
}
|
|
|
|
// 1-9
|
|
if (0x31 <= code && code <= 0x39) {
|
|
return 'number'
|
|
}
|
|
|
|
return 'else'
|
|
}
|
|
|
|
/**
|
|
* Parse a string path into an array of segments
|
|
* Todo implement cache
|
|
*
|
|
* @param {String} path
|
|
* @return {Array|undefined}
|
|
*/
|
|
|
|
function parsePath (path) {
|
|
var keys = []
|
|
var index = -1
|
|
var mode = 'beforePath'
|
|
var c, newChar, key, type, transition, action, typeMap
|
|
|
|
var actions = {
|
|
push: function() {
|
|
if (key === undefined) {
|
|
return
|
|
}
|
|
keys.push(key)
|
|
key = undefined
|
|
},
|
|
append: function() {
|
|
if (key === undefined) {
|
|
key = newChar
|
|
} else {
|
|
key += newChar
|
|
}
|
|
}
|
|
}
|
|
|
|
function maybeUnescapeQuote () {
|
|
var nextChar = path[index + 1]
|
|
if ((mode === 'inSingleQuote' && nextChar === "'") ||
|
|
(mode === 'inDoubleQuote' && nextChar === '"')) {
|
|
index++
|
|
newChar = nextChar
|
|
actions.append()
|
|
return true
|
|
}
|
|
}
|
|
|
|
while (mode) {
|
|
index++
|
|
c = path[index]
|
|
|
|
if (c === '\\' && maybeUnescapeQuote()) {
|
|
continue
|
|
}
|
|
|
|
type = getPathCharType(c)
|
|
typeMap = pathStateMachine[mode]
|
|
transition = typeMap[type] || typeMap['else'] || 'error'
|
|
|
|
if (transition === 'error') {
|
|
return // parse error
|
|
}
|
|
|
|
mode = transition[0]
|
|
action = actions[transition[1]] || noop
|
|
newChar = transition[2] === undefined
|
|
? c
|
|
: transition[2]
|
|
action()
|
|
|
|
if (mode === 'afterPath') {
|
|
return keys
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Format a accessor segment based on its type.
|
|
*
|
|
* @param {String} key
|
|
* @return {Boolean}
|
|
*/
|
|
|
|
function formatAccessor(key) {
|
|
if (identRE.test(key)) { // identifier
|
|
return '.' + key
|
|
} else if (+key === key >>> 0) { // bracket index
|
|
return '[' + key + ']';
|
|
} else { // bracket string
|
|
return '["' + key.replace(/"/g, '\\"') + '"]';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compiles a getter function with a fixed path.
|
|
*
|
|
* @param {Array} path
|
|
* @return {Function}
|
|
*/
|
|
|
|
exports.compileGetter = function (path) {
|
|
var body =
|
|
'try{return o' +
|
|
path.map(formatAccessor).join('') +
|
|
'}catch(e){};'
|
|
return new Function('o', body)
|
|
}
|
|
|
|
/**
|
|
* External parse that check for a cache hit first
|
|
*
|
|
* @param {String} path
|
|
* @return {Array|undefined}
|
|
*/
|
|
|
|
exports.parse = function (path) {
|
|
var hit = pathCache.get(path)
|
|
if (!hit) {
|
|
hit = parsePath(path)
|
|
if (hit) {
|
|
hit.get = exports.compileGetter(hit)
|
|
pathCache.put(path, hit)
|
|
}
|
|
}
|
|
return hit
|
|
}
|
|
|
|
/**
|
|
* Get from an object from a path string
|
|
*
|
|
* @param {Object} obj
|
|
* @param {String} path
|
|
*/
|
|
|
|
exports.get = function (obj, path) {
|
|
path = exports.parse(path)
|
|
if (path) {
|
|
return path.get(obj)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set on an object from a path
|
|
*
|
|
* @param {Object} obj
|
|
* @param {String | Array} path
|
|
* @param {*} val
|
|
*/
|
|
|
|
exports.set = function (obj, path, val) {
|
|
if (typeof path === 'string') {
|
|
path = exports.parse(path)
|
|
}
|
|
if (!path || !_.isObject(obj)) {
|
|
return false
|
|
}
|
|
var last, key
|
|
for (var i = 0, l = path.length - 1; i < l; i++) {
|
|
last = obj
|
|
key = path[i]
|
|
obj = obj[key]
|
|
if (!_.isObject(obj)) {
|
|
obj = {}
|
|
last.$add(key, obj)
|
|
}
|
|
}
|
|
key = path[i]
|
|
if (key in obj) {
|
|
obj[key] = val
|
|
} else {
|
|
obj.$add(key, val)
|
|
}
|
|
return true
|
|
}
|
|
|
|
/***/ },
|
|
/* 42 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Cache = __webpack_require__(52)
|
|
var config = __webpack_require__(20)
|
|
var dirParser = __webpack_require__(43)
|
|
var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g
|
|
var cache, tagRE, htmlRE, firstChar, lastChar
|
|
|
|
/**
|
|
* Escape a string so it can be used in a RegExp
|
|
* constructor.
|
|
*
|
|
* @param {String} str
|
|
*/
|
|
|
|
function escapeRegex (str) {
|
|
return str.replace(regexEscapeRE, '\\$&')
|
|
}
|
|
|
|
/**
|
|
* Compile the interpolation tag regex.
|
|
*
|
|
* @return {RegExp}
|
|
*/
|
|
|
|
function compileRegex () {
|
|
config._delimitersChanged = false
|
|
var open = config.delimiters[0]
|
|
var close = config.delimiters[1]
|
|
firstChar = open.charAt(0)
|
|
lastChar = close.charAt(close.length - 1)
|
|
var firstCharRE = escapeRegex(firstChar)
|
|
var lastCharRE = escapeRegex(lastChar)
|
|
var openRE = escapeRegex(open)
|
|
var closeRE = escapeRegex(close)
|
|
tagRE = new RegExp(
|
|
firstCharRE + '?' + openRE +
|
|
'(.+?)' +
|
|
closeRE + lastCharRE + '?',
|
|
'g'
|
|
)
|
|
htmlRE = new RegExp(
|
|
'^' + firstCharRE + openRE +
|
|
'.*' +
|
|
closeRE + lastCharRE + '$'
|
|
)
|
|
// reset cache
|
|
cache = new Cache(1000)
|
|
}
|
|
|
|
/**
|
|
* Parse a template text string into an array of tokens.
|
|
*
|
|
* @param {String} text
|
|
* @return {Array<Object> | null}
|
|
* - {String} type
|
|
* - {String} value
|
|
* - {Boolean} [html]
|
|
* - {Boolean} [oneTime]
|
|
*/
|
|
|
|
exports.parse = function (text) {
|
|
if (config._delimitersChanged) {
|
|
compileRegex()
|
|
}
|
|
var hit = cache.get(text)
|
|
if (hit) {
|
|
return hit
|
|
}
|
|
if (!tagRE.test(text)) {
|
|
return null
|
|
}
|
|
var tokens = []
|
|
var lastIndex = tagRE.lastIndex = 0
|
|
var match, index, value, first, oneTime, partial
|
|
/* jshint boss:true */
|
|
while (match = tagRE.exec(text)) {
|
|
index = match.index
|
|
// push text token
|
|
if (index > lastIndex) {
|
|
tokens.push({
|
|
value: text.slice(lastIndex, index)
|
|
})
|
|
}
|
|
// tag token
|
|
first = match[1].charCodeAt(0)
|
|
oneTime = first === 0x2A // *
|
|
partial = first === 0x3E // >
|
|
value = (oneTime || partial)
|
|
? match[1].slice(1)
|
|
: match[1]
|
|
tokens.push({
|
|
tag: true,
|
|
value: value.trim(),
|
|
html: htmlRE.test(match[0]),
|
|
oneTime: oneTime,
|
|
partial: partial
|
|
})
|
|
lastIndex = index + match[0].length
|
|
}
|
|
if (lastIndex < text.length) {
|
|
tokens.push({
|
|
value: text.slice(lastIndex)
|
|
})
|
|
}
|
|
cache.put(text, tokens)
|
|
return tokens
|
|
}
|
|
|
|
/**
|
|
* Format a list of tokens into an expression.
|
|
* e.g. tokens parsed from 'a {{b}} c' can be serialized
|
|
* into one single expression as '"a " + b + " c"'.
|
|
*
|
|
* @param {Array} tokens
|
|
* @param {Vue} [vm]
|
|
* @return {String}
|
|
*/
|
|
|
|
exports.tokensToExp = function (tokens, vm) {
|
|
return tokens.length > 1
|
|
? tokens.map(function (token) {
|
|
return formatToken(token, vm)
|
|
}).join('+')
|
|
: formatToken(tokens[0], vm, true)
|
|
}
|
|
|
|
/**
|
|
* Format a single token.
|
|
*
|
|
* @param {Object} token
|
|
* @param {Vue} [vm]
|
|
* @param {Boolean} single
|
|
* @return {String}
|
|
*/
|
|
|
|
function formatToken (token, vm, single) {
|
|
return token.tag
|
|
? vm && token.oneTime
|
|
? '"' + vm.$eval(token.value) + '"'
|
|
: single
|
|
? token.value
|
|
: inlineFilters(token.value)
|
|
: '"' + token.value + '"'
|
|
}
|
|
|
|
/**
|
|
* For an attribute with multiple interpolation tags,
|
|
* e.g. attr="some-{{thing | filter}}", in order to combine
|
|
* the whole thing into a single watchable expression, we
|
|
* have to inline those filters. This function does exactly
|
|
* that. This is a bit hacky but it avoids heavy changes
|
|
* to directive parser and watcher mechanism.
|
|
*
|
|
* @param {String} exp
|
|
* @return {String}
|
|
*/
|
|
|
|
var filterRE = /[^|]\|[^|]/
|
|
function inlineFilters (exp) {
|
|
if (!filterRE.test(exp)) {
|
|
return '(' + exp + ')'
|
|
} else {
|
|
var dir = dirParser.parse(exp)[0]
|
|
if (!dir.filters) {
|
|
return '(' + exp + ')'
|
|
} else {
|
|
exp = dir.expression
|
|
for (var i = 0, l = dir.filters.length; i < l; i++) {
|
|
var filter = dir.filters[i]
|
|
var args = filter.args
|
|
? ',"' + filter.args.join('","') + '"'
|
|
: ''
|
|
exp = 'this.$options.filters["' + filter.name + '"]' +
|
|
'.apply(this,[' + exp + args + '])'
|
|
}
|
|
return exp
|
|
}
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 43 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var Cache = __webpack_require__(52)
|
|
var cache = new Cache(1000)
|
|
var argRE = /^[^\{\?]+$|^'[^']*'$|^"[^"]*"$/
|
|
var filterTokenRE = /[^\s'"]+|'[^']+'|"[^"]+"/g
|
|
|
|
/**
|
|
* Parser state
|
|
*/
|
|
|
|
var str
|
|
var c, i, l
|
|
var inSingle
|
|
var inDouble
|
|
var curly
|
|
var square
|
|
var paren
|
|
var begin
|
|
var argIndex
|
|
var dirs
|
|
var dir
|
|
var lastFilterIndex
|
|
var arg
|
|
|
|
/**
|
|
* Push a directive object into the result Array
|
|
*/
|
|
|
|
function pushDir () {
|
|
dir.raw = str.slice(begin, i).trim()
|
|
if (dir.expression === undefined) {
|
|
dir.expression = str.slice(argIndex, i).trim()
|
|
} else if (lastFilterIndex !== begin) {
|
|
pushFilter()
|
|
}
|
|
if (i === 0 || dir.expression) {
|
|
dirs.push(dir)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Push a filter to the current directive object
|
|
*/
|
|
|
|
function pushFilter () {
|
|
var exp = str.slice(lastFilterIndex, i).trim()
|
|
var filter
|
|
if (exp) {
|
|
filter = {}
|
|
var tokens = exp.match(filterTokenRE)
|
|
filter.name = tokens[0]
|
|
filter.args = tokens.length > 1 ? tokens.slice(1) : null
|
|
}
|
|
if (filter) {
|
|
(dir.filters = dir.filters || []).push(filter)
|
|
}
|
|
lastFilterIndex = i + 1
|
|
}
|
|
|
|
/**
|
|
* Parse a directive string into an Array of AST-like
|
|
* objects representing directives.
|
|
*
|
|
* Example:
|
|
*
|
|
* "click: a = a + 1 | uppercase" will yield:
|
|
* {
|
|
* arg: 'click',
|
|
* expression: 'a = a + 1',
|
|
* filters: [
|
|
* { name: 'uppercase', args: null }
|
|
* ]
|
|
* }
|
|
*
|
|
* @param {String} str
|
|
* @return {Array<Object>}
|
|
*/
|
|
|
|
exports.parse = function (s) {
|
|
|
|
var hit = cache.get(s)
|
|
if (hit) {
|
|
return hit
|
|
}
|
|
|
|
// reset parser state
|
|
str = s
|
|
inSingle = inDouble = false
|
|
curly = square = paren = begin = argIndex = 0
|
|
lastFilterIndex = 0
|
|
dirs = []
|
|
dir = {}
|
|
arg = null
|
|
|
|
for (i = 0, l = str.length; i < l; i++) {
|
|
c = str.charCodeAt(i)
|
|
if (inSingle) {
|
|
// check single quote
|
|
if (c === 0x27) inSingle = !inSingle
|
|
} else if (inDouble) {
|
|
// check double quote
|
|
if (c === 0x22) inDouble = !inDouble
|
|
} else if (
|
|
c === 0x2C && // comma
|
|
!paren && !curly && !square
|
|
) {
|
|
// reached the end of a directive
|
|
pushDir()
|
|
// reset & skip the comma
|
|
dir = {}
|
|
begin = argIndex = lastFilterIndex = i + 1
|
|
} else if (
|
|
c === 0x3A && // colon
|
|
!dir.expression &&
|
|
!dir.arg
|
|
) {
|
|
// argument
|
|
arg = str.slice(begin, i).trim()
|
|
// test for valid argument here
|
|
// since we may have caught stuff like first half of
|
|
// an object literal or a ternary expression.
|
|
if (argRE.test(arg)) {
|
|
argIndex = i + 1
|
|
dir.arg = _.stripQuotes(arg) || arg
|
|
}
|
|
} else if (
|
|
c === 0x7C && // pipe
|
|
str.charCodeAt(i + 1) !== 0x7C &&
|
|
str.charCodeAt(i - 1) !== 0x7C
|
|
) {
|
|
if (dir.expression === undefined) {
|
|
// first filter, end of expression
|
|
lastFilterIndex = i + 1
|
|
dir.expression = str.slice(argIndex, i).trim()
|
|
} else {
|
|
// already has filter
|
|
pushFilter()
|
|
}
|
|
} else {
|
|
switch (c) {
|
|
case 0x22: inDouble = true; break // "
|
|
case 0x27: inSingle = true; break // '
|
|
case 0x28: paren++; break // (
|
|
case 0x29: paren--; break // )
|
|
case 0x5B: square++; break // [
|
|
case 0x5D: square--; break // ]
|
|
case 0x7B: curly++; break // {
|
|
case 0x7D: curly--; break // }
|
|
}
|
|
}
|
|
}
|
|
|
|
if (i === 0 || begin !== i) {
|
|
pushDir()
|
|
}
|
|
|
|
cache.put(s, dirs)
|
|
return dirs
|
|
}
|
|
|
|
/***/ },
|
|
/* 44 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var Path = __webpack_require__(41)
|
|
var Cache = __webpack_require__(52)
|
|
var expressionCache = new Cache(1000)
|
|
|
|
var keywords =
|
|
'Math,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,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,' +
|
|
'arguments,let,yield'
|
|
|
|
var wsRE = /\s/g
|
|
var newlineRE = /\n/g
|
|
var saveRE = /[\{,]\s*[\w\$_]+\s*:|'[^']*'|"[^"]*"/g
|
|
var restoreRE = /"(\d+)"/g
|
|
var pathTestRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\])*$/
|
|
var pathReplaceRE = /[^\w$\.]([A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\])*)/g
|
|
var keywordsRE = new RegExp('^(' + keywords.replace(/,/g, '\\b|') + '\\b)')
|
|
|
|
/**
|
|
* Save / Rewrite / Restore
|
|
*
|
|
* When rewriting paths found in an expression, it is
|
|
* possible for the same letter sequences to be found in
|
|
* strings and Object literal property keys. Therefore we
|
|
* remove and store these parts in a temporary array, and
|
|
* restore them after the path rewrite.
|
|
*/
|
|
|
|
var saved = []
|
|
|
|
/**
|
|
* Save replacer
|
|
*
|
|
* @param {String} str
|
|
* @return {String} - placeholder with index
|
|
*/
|
|
|
|
function save (str) {
|
|
var i = saved.length
|
|
saved[i] = str.replace(newlineRE, '\\n')
|
|
return '"' + i + '"'
|
|
}
|
|
|
|
/**
|
|
* Path rewrite replacer
|
|
*
|
|
* @param {String} raw
|
|
* @return {String}
|
|
*/
|
|
|
|
function rewrite (raw) {
|
|
var c = raw.charAt(0)
|
|
var path = raw.slice(1)
|
|
if (keywordsRE.test(path)) {
|
|
return raw
|
|
} else {
|
|
path = path.indexOf('"') > -1
|
|
? path.replace(restoreRE, restore)
|
|
: path
|
|
return c + 'scope.' + path
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Restore replacer
|
|
*
|
|
* @param {String} str
|
|
* @param {String} i - matched save index
|
|
* @return {String}
|
|
*/
|
|
|
|
function restore (str, i) {
|
|
return saved[i]
|
|
}
|
|
|
|
/**
|
|
* Rewrite an expression, prefixing all path accessors with
|
|
* `scope.` and generate getter/setter functions.
|
|
*
|
|
* @param {String} exp
|
|
* @param {Boolean} needSet
|
|
* @return {Function}
|
|
*/
|
|
|
|
function compileExpFns (exp, needSet) {
|
|
// reset state
|
|
saved.length = 0
|
|
// save strings and object literal keys
|
|
var body = exp
|
|
.replace(saveRE, save)
|
|
.replace(wsRE, '')
|
|
// rewrite all paths
|
|
// pad 1 space here becaue the regex matches 1 extra char
|
|
body = (' ' + body)
|
|
.replace(pathReplaceRE, rewrite)
|
|
.replace(restoreRE, restore)
|
|
var getter = makeGetter(body)
|
|
if (getter) {
|
|
return {
|
|
get: getter,
|
|
body: body,
|
|
set: needSet
|
|
? makeSetter(body)
|
|
: null
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compile getter setters for a simple path.
|
|
*
|
|
* @param {String} exp
|
|
* @return {Function}
|
|
*/
|
|
|
|
function compilePathFns (exp) {
|
|
var getter, path
|
|
if (exp.indexOf('[') < 0) {
|
|
// really simple path
|
|
path = exp.split('.')
|
|
getter = Path.compileGetter(path)
|
|
} else {
|
|
// do the real parsing
|
|
path = Path.parse(exp)
|
|
getter = path.get
|
|
}
|
|
return {
|
|
get: getter,
|
|
// always generate setter for simple paths
|
|
set: function (obj, val) {
|
|
Path.set(obj, path, val)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build a getter function. Requires eval.
|
|
*
|
|
* We isolate the try/catch so it doesn't affect the
|
|
* optimization of the parse function when it is not called.
|
|
*
|
|
* @param {String} body
|
|
* @return {Function|undefined}
|
|
*/
|
|
|
|
function makeGetter (body) {
|
|
try {
|
|
return new Function('scope', 'return ' + body + ';')
|
|
} catch (e) {
|
|
_.warn(
|
|
'Invalid expression. ' +
|
|
'Generated function body: ' + body
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build a setter function.
|
|
*
|
|
* This is only needed in rare situations like "a[b]" where
|
|
* a settable path requires dynamic evaluation.
|
|
*
|
|
* This setter function may throw error when called if the
|
|
* expression body is not a valid left-hand expression in
|
|
* assignment.
|
|
*
|
|
* @param {String} body
|
|
* @return {Function|undefined}
|
|
*/
|
|
|
|
function makeSetter (body) {
|
|
try {
|
|
return new Function('scope', 'value', body + '=value;')
|
|
} catch (e) {
|
|
_.warn('Invalid setter function body: ' + body)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check for setter existence on a cache hit.
|
|
*
|
|
* @param {Function} hit
|
|
*/
|
|
|
|
function checkSetter (hit) {
|
|
if (!hit.set) {
|
|
hit.set = makeSetter(hit.body)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parse an expression into re-written getter/setters.
|
|
*
|
|
* @param {String} exp
|
|
* @param {Boolean} needSet
|
|
* @return {Function}
|
|
*/
|
|
|
|
exports.parse = function (exp, needSet) {
|
|
exp = exp.trim()
|
|
// try cache
|
|
var hit = expressionCache.get(exp)
|
|
if (hit) {
|
|
if (needSet) {
|
|
checkSetter(hit)
|
|
}
|
|
return hit
|
|
}
|
|
// we do a simple path check to optimize for them.
|
|
// the check fails valid paths with unusal whitespaces,
|
|
// but that's too rare and we don't care.
|
|
var res = pathTestRE.test(exp)
|
|
? compilePathFns(exp)
|
|
: compileExpFns(exp, needSet)
|
|
expressionCache.put(exp, res)
|
|
return res
|
|
}
|
|
|
|
// Export the pathRegex for external use
|
|
exports.pathTestRE = pathTestRE
|
|
|
|
/***/ },
|
|
/* 45 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var applyCSSTransition = __webpack_require__(53)
|
|
var applyJSTransition = __webpack_require__(54)
|
|
|
|
/**
|
|
* Append with transition.
|
|
*
|
|
* @oaram {Element} el
|
|
* @param {Element} target
|
|
* @param {Vue} vm
|
|
* @param {Function} [cb]
|
|
*/
|
|
|
|
exports.append = function (el, target, vm, cb) {
|
|
apply(el, 1, function () {
|
|
target.appendChild(el)
|
|
}, vm, cb)
|
|
}
|
|
|
|
/**
|
|
* InsertBefore with transition.
|
|
*
|
|
* @oaram {Element} el
|
|
* @param {Element} target
|
|
* @param {Vue} vm
|
|
* @param {Function} [cb]
|
|
*/
|
|
|
|
exports.before = function (el, target, vm, cb) {
|
|
apply(el, 1, function () {
|
|
_.before(el, target)
|
|
}, vm, cb)
|
|
}
|
|
|
|
/**
|
|
* Remove with transition.
|
|
*
|
|
* @oaram {Element} el
|
|
* @param {Vue} vm
|
|
* @param {Function} [cb]
|
|
*/
|
|
|
|
exports.remove = function (el, vm, cb) {
|
|
apply(el, -1, function () {
|
|
_.remove(el)
|
|
}, vm, cb)
|
|
}
|
|
|
|
/**
|
|
* Remove by appending to another parent with transition.
|
|
* This is only used in block operations.
|
|
*
|
|
* @oaram {Element} el
|
|
* @param {Element} target
|
|
* @param {Vue} vm
|
|
* @param {Function} [cb]
|
|
*/
|
|
|
|
exports.removeThenAppend = function (el, target, vm, cb) {
|
|
apply(el, -1, function () {
|
|
target.appendChild(el)
|
|
}, vm, cb)
|
|
}
|
|
|
|
/**
|
|
* Append the childNodes of a fragment to target.
|
|
*
|
|
* @param {DocumentFragment} block
|
|
* @param {Node} target
|
|
* @param {Vue} vm
|
|
*/
|
|
|
|
exports.blockAppend = function (block, target, vm) {
|
|
var nodes = _.toArray(block.childNodes)
|
|
for (var i = 0, l = nodes.length; i < l; i++) {
|
|
exports.before(nodes[i], target, vm)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove a block of nodes between two edge nodes.
|
|
*
|
|
* @param {Node} start
|
|
* @param {Node} end
|
|
* @param {Vue} vm
|
|
*/
|
|
|
|
exports.blockRemove = function (start, end, vm) {
|
|
var node = start.nextSibling
|
|
var next
|
|
while (node !== end) {
|
|
next = node.nextSibling
|
|
exports.remove(node, vm)
|
|
node = next
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply transitions with an operation callback.
|
|
*
|
|
* @oaram {Element} el
|
|
* @param {Number} direction
|
|
* 1: enter
|
|
* -1: leave
|
|
* @param {Function} op - the actual DOM operation
|
|
* @param {Vue} vm
|
|
* @param {Function} [cb]
|
|
*/
|
|
|
|
var apply = exports.apply = function (el, direction, op, vm, cb) {
|
|
var transData = el.__v_trans
|
|
if (
|
|
!transData ||
|
|
!vm._isCompiled ||
|
|
// if the vm is being manipulated by a parent directive
|
|
// during the parent's compilation phase, skip the
|
|
// animation.
|
|
(vm.$parent && !vm.$parent._isCompiled)
|
|
) {
|
|
op()
|
|
if (cb) cb()
|
|
return
|
|
}
|
|
// determine the transition type on the element
|
|
var jsTransition = vm.$options.transitions[transData.id]
|
|
if (jsTransition) {
|
|
// js
|
|
applyJSTransition(
|
|
el,
|
|
direction,
|
|
op,
|
|
transData,
|
|
jsTransition,
|
|
vm,
|
|
cb
|
|
)
|
|
} else if (_.transitionEndEvent) {
|
|
// css
|
|
applyCSSTransition(
|
|
el,
|
|
direction,
|
|
op,
|
|
transData,
|
|
cb
|
|
)
|
|
} else {
|
|
// not applicable
|
|
op()
|
|
if (cb) cb()
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 46 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var config = __webpack_require__(20)
|
|
var textParser = __webpack_require__(42)
|
|
var dirParser = __webpack_require__(43)
|
|
var templateParser = __webpack_require__(51)
|
|
|
|
/**
|
|
* Compile a template and return a reusable composite link
|
|
* function, which recursively contains more link functions
|
|
* inside. This top level compile function should only be
|
|
* called on instance root nodes.
|
|
*
|
|
* @param {Element|DocumentFragment} el
|
|
* @param {Object} options
|
|
* @param {Boolean} partial
|
|
* @return {Function}
|
|
*/
|
|
|
|
module.exports = function compile (el, options, partial) {
|
|
var params = !partial && options.paramAttributes
|
|
var paramsLinkFn = params
|
|
? compileParamAttributes(el, params, options)
|
|
: null
|
|
var nodeLinkFn = el instanceof DocumentFragment
|
|
? null
|
|
: compileNode(el, options)
|
|
var childLinkFn =
|
|
(!nodeLinkFn || !nodeLinkFn.terminal) &&
|
|
el.hasChildNodes()
|
|
? compileNodeList(el.childNodes, options)
|
|
: null
|
|
|
|
/**
|
|
* A linker function to be called on a already compiled
|
|
* piece of DOM, which instantiates all directive
|
|
* instances.
|
|
*
|
|
* @param {Vue} vm
|
|
* @param {Element|DocumentFragment} el
|
|
* @return {Function|undefined}
|
|
*/
|
|
|
|
return function link (vm, el) {
|
|
var originalDirCount = vm._directives.length
|
|
if (paramsLinkFn) paramsLinkFn(vm, el)
|
|
if (nodeLinkFn) nodeLinkFn(vm, el)
|
|
if (childLinkFn) childLinkFn(vm, el.childNodes)
|
|
|
|
/**
|
|
* If this is a partial compile, the linker function
|
|
* returns an unlink function that tearsdown all
|
|
* directives instances generated during the partial
|
|
* linking.
|
|
*/
|
|
|
|
if (partial) {
|
|
var dirs = vm._directives.slice(originalDirCount)
|
|
return function unlink () {
|
|
var i = dirs.length
|
|
while (i--) {
|
|
dirs[i]._teardown()
|
|
}
|
|
i = vm._directives.indexOf(dirs[0])
|
|
vm._directives.splice(i, dirs.length)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compile a node and return a nodeLinkFn based on the
|
|
* node type.
|
|
*
|
|
* @param {Node} node
|
|
* @param {Object} options
|
|
* @return {Function|undefined}
|
|
*/
|
|
|
|
function compileNode (node, options) {
|
|
var type = node.nodeType
|
|
if (type === 1 && node.tagName !== 'SCRIPT') {
|
|
return compileElement(node, options)
|
|
} else if (type === 3 && config.interpolate) {
|
|
return compileTextNode(node, options)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compile an element and return a nodeLinkFn.
|
|
*
|
|
* @param {Element} el
|
|
* @param {Object} options
|
|
* @return {Function|null}
|
|
*/
|
|
|
|
function compileElement (el, options) {
|
|
var linkFn, tag, component
|
|
// check custom element component, but only on non-root
|
|
if (!el.__vue__) {
|
|
tag = el.tagName.toLowerCase()
|
|
component =
|
|
tag.indexOf('-') > 0 &&
|
|
options.components[tag]
|
|
if (component) {
|
|
el.setAttribute(config.prefix + 'component', tag)
|
|
}
|
|
}
|
|
if (component || el.hasAttributes()) {
|
|
// check terminal direcitves
|
|
linkFn = checkTerminalDirectives(el, options)
|
|
// if not terminal, build normal link function
|
|
if (!linkFn) {
|
|
var directives = collectDirectives(el, options)
|
|
linkFn = directives.length
|
|
? makeDirectivesLinkFn(directives)
|
|
: null
|
|
}
|
|
}
|
|
// if the element is a textarea, we need to interpolate
|
|
// its content on initial render.
|
|
if (el.tagName === 'TEXTAREA') {
|
|
var realLinkFn = linkFn
|
|
linkFn = function (vm, el) {
|
|
el.value = vm.$interpolate(el.value)
|
|
if (realLinkFn) realLinkFn(vm, el)
|
|
}
|
|
linkFn.terminal = true
|
|
}
|
|
return linkFn
|
|
}
|
|
|
|
/**
|
|
* Build a multi-directive link function.
|
|
*
|
|
* @param {Array} directives
|
|
* @return {Function} directivesLinkFn
|
|
*/
|
|
|
|
function makeDirectivesLinkFn (directives) {
|
|
return function directivesLinkFn (vm, el) {
|
|
// reverse apply because it's sorted low to high
|
|
var i = directives.length
|
|
var dir, j, k
|
|
while (i--) {
|
|
dir = directives[i]
|
|
if (dir._link) {
|
|
// custom link fn
|
|
dir._link(vm, el)
|
|
} else {
|
|
k = dir.descriptors.length
|
|
for (j = 0; j < k; j++) {
|
|
vm._bindDir(dir.name, el,
|
|
dir.descriptors[j], dir.def)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compile a textNode and return a nodeLinkFn.
|
|
*
|
|
* @param {TextNode} node
|
|
* @param {Object} options
|
|
* @return {Function|null} textNodeLinkFn
|
|
*/
|
|
|
|
function compileTextNode (node, options) {
|
|
var tokens = textParser.parse(node.nodeValue)
|
|
if (!tokens) {
|
|
return null
|
|
}
|
|
var frag = document.createDocumentFragment()
|
|
var dirs = options.directives
|
|
var el, token, value
|
|
for (var i = 0, l = tokens.length; i < l; i++) {
|
|
token = tokens[i]
|
|
value = token.value
|
|
if (token.tag) {
|
|
if (token.oneTime) {
|
|
el = document.createTextNode(value)
|
|
} else {
|
|
if (token.html) {
|
|
el = document.createComment('v-html')
|
|
token.type = 'html'
|
|
token.def = dirs.html
|
|
token.descriptor = dirParser.parse(value)[0]
|
|
} else if (token.partial) {
|
|
el = document.createComment('v-partial')
|
|
token.type = 'partial'
|
|
token.def = dirs.partial
|
|
token.descriptor = dirParser.parse(value)[0]
|
|
} else {
|
|
// IE will clean up empty textNodes during
|
|
// frag.cloneNode(true), so we have to give it
|
|
// something here...
|
|
el = document.createTextNode(' ')
|
|
token.type = 'text'
|
|
token.def = dirs.text
|
|
token.descriptor = dirParser.parse(value)[0]
|
|
}
|
|
}
|
|
} else {
|
|
el = document.createTextNode(value)
|
|
}
|
|
frag.appendChild(el)
|
|
}
|
|
return makeTextNodeLinkFn(tokens, frag, options)
|
|
}
|
|
|
|
/**
|
|
* Build a function that processes a textNode.
|
|
*
|
|
* @param {Array<Object>} tokens
|
|
* @param {DocumentFragment} frag
|
|
*/
|
|
|
|
function makeTextNodeLinkFn (tokens, frag) {
|
|
return function textNodeLinkFn (vm, el) {
|
|
var fragClone = frag.cloneNode(true)
|
|
var childNodes = _.toArray(fragClone.childNodes)
|
|
var token, value, node
|
|
for (var i = 0, l = tokens.length; i < l; i++) {
|
|
token = tokens[i]
|
|
value = token.value
|
|
if (token.tag) {
|
|
node = childNodes[i]
|
|
if (token.oneTime) {
|
|
value = vm.$eval(value)
|
|
if (token.html) {
|
|
_.replace(node, templateParser.parse(value, true))
|
|
} else {
|
|
node.nodeValue = value
|
|
}
|
|
} else {
|
|
vm._bindDir(token.type, node,
|
|
token.descriptor, token.def)
|
|
}
|
|
}
|
|
}
|
|
_.replace(el, fragClone)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compile a node list and return a childLinkFn.
|
|
*
|
|
* @param {NodeList} nodeList
|
|
* @param {Object} options
|
|
* @return {Function|undefined}
|
|
*/
|
|
|
|
function compileNodeList (nodeList, options) {
|
|
var linkFns = []
|
|
var nodeLinkFn, childLinkFn, node
|
|
for (var i = 0, l = nodeList.length; i < l; i++) {
|
|
node = nodeList[i]
|
|
nodeLinkFn = compileNode(node, options)
|
|
childLinkFn =
|
|
(!nodeLinkFn || !nodeLinkFn.terminal) &&
|
|
node.hasChildNodes()
|
|
? compileNodeList(node.childNodes, options)
|
|
: null
|
|
linkFns.push(nodeLinkFn, childLinkFn)
|
|
}
|
|
return linkFns.length
|
|
? makeChildLinkFn(linkFns)
|
|
: null
|
|
}
|
|
|
|
/**
|
|
* Make a child link function for a node's childNodes.
|
|
*
|
|
* @param {Array<Function>} linkFns
|
|
* @return {Function} childLinkFn
|
|
*/
|
|
|
|
function makeChildLinkFn (linkFns) {
|
|
return function childLinkFn (vm, nodes) {
|
|
// stablize nodes
|
|
nodes = _.toArray(nodes)
|
|
var node, nodeLinkFn, childrenLinkFn
|
|
for (var i = 0, n = 0, l = linkFns.length; i < l; n++) {
|
|
node = nodes[n]
|
|
nodeLinkFn = linkFns[i++]
|
|
childrenLinkFn = linkFns[i++]
|
|
if (nodeLinkFn) {
|
|
nodeLinkFn(vm, node)
|
|
}
|
|
if (childrenLinkFn) {
|
|
childrenLinkFn(vm, node.childNodes)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compile param attributes on a root element and return
|
|
* a paramAttributes link function.
|
|
*
|
|
* @param {Element} el
|
|
* @param {Array} attrs
|
|
* @param {Object} options
|
|
* @return {Function} paramsLinkFn
|
|
*/
|
|
|
|
function compileParamAttributes (el, attrs, options) {
|
|
var params = []
|
|
var i = attrs.length
|
|
var name, value, param
|
|
while (i--) {
|
|
name = attrs[i]
|
|
value = el.getAttribute(name)
|
|
if (value !== null) {
|
|
param = {
|
|
name: name,
|
|
value: value
|
|
}
|
|
var tokens = textParser.parse(value)
|
|
if (tokens) {
|
|
el.removeAttribute(name)
|
|
if (tokens.length > 1) {
|
|
_.warn(
|
|
'Invalid param attribute binding: "' +
|
|
name + '="' + value + '"' +
|
|
'\nDon\'t mix binding tags with plain text ' +
|
|
'in param attribute bindings.'
|
|
)
|
|
continue
|
|
} else {
|
|
param.dynamic = true
|
|
param.value = tokens[0].value
|
|
}
|
|
}
|
|
params.push(param)
|
|
}
|
|
}
|
|
return makeParamsLinkFn(params, options)
|
|
}
|
|
|
|
/**
|
|
* Build a function that applies param attributes to a vm.
|
|
*
|
|
* @param {Array} params
|
|
* @param {Object} options
|
|
* @return {Function} paramsLinkFn
|
|
*/
|
|
|
|
var dataAttrRE = /^data-/
|
|
|
|
function makeParamsLinkFn (params, options) {
|
|
var def = options.directives['with']
|
|
return function paramsLinkFn (vm, el) {
|
|
var i = params.length
|
|
var param, path
|
|
while (i--) {
|
|
param = params[i]
|
|
// params could contain dashes, which will be
|
|
// interpreted as minus calculations by the parser
|
|
// so we need to wrap the path here
|
|
path = _.camelize(param.name.replace(dataAttrRE, ''))
|
|
if (param.dynamic) {
|
|
// dynamic param attribtues are bound as v-with.
|
|
// we can directly duck the descriptor here beacuse
|
|
// param attributes cannot use expressions or
|
|
// filters.
|
|
vm._bindDir('with', el, {
|
|
arg: path,
|
|
expression: param.value
|
|
}, def)
|
|
} else {
|
|
// just set once
|
|
vm.$set(path, param.value)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check an element for terminal directives in fixed order.
|
|
* If it finds one, return a terminal link function.
|
|
*
|
|
* @param {Element} el
|
|
* @param {Object} options
|
|
* @return {Function} terminalLinkFn
|
|
*/
|
|
|
|
var terminalDirectives = [
|
|
'repeat',
|
|
'if',
|
|
'component'
|
|
]
|
|
|
|
function skip () {}
|
|
skip.terminal = true
|
|
|
|
function checkTerminalDirectives (el, options) {
|
|
if (_.attr(el, 'pre') !== null) {
|
|
return skip
|
|
}
|
|
var value, dirName
|
|
/* jshint boss: true */
|
|
for (var i = 0; i < 3; i++) {
|
|
dirName = terminalDirectives[i]
|
|
if (value = _.attr(el, dirName)) {
|
|
return makeTeriminalLinkFn(el, dirName, value, options)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build a link function for a terminal directive.
|
|
*
|
|
* @param {Element} el
|
|
* @param {String} dirName
|
|
* @param {String} value
|
|
* @param {Object} options
|
|
* @return {Function} terminalLinkFn
|
|
*/
|
|
|
|
function makeTeriminalLinkFn (el, dirName, value, options) {
|
|
var descriptor = dirParser.parse(value)[0]
|
|
var def = options.directives[dirName]
|
|
// special case: we need to collect directives found
|
|
// on a component root node, but defined in the parent
|
|
// template. These directives need to be compiled in
|
|
// the parent scope.
|
|
if (dirName === 'component') {
|
|
var dirs = collectDirectives(el, options, true)
|
|
el._parentLinker = dirs.length
|
|
? makeDirectivesLinkFn(dirs)
|
|
: null
|
|
}
|
|
var terminalLinkFn = function (vm, el) {
|
|
vm._bindDir(dirName, el, descriptor, def)
|
|
}
|
|
terminalLinkFn.terminal = true
|
|
return terminalLinkFn
|
|
}
|
|
|
|
/**
|
|
* Collect the directives on an element.
|
|
*
|
|
* @param {Element} el
|
|
* @param {Object} options
|
|
* @param {Boolean} asParent
|
|
* @return {Array}
|
|
*/
|
|
|
|
function collectDirectives (el, options, asParent) {
|
|
var attrs = _.toArray(el.attributes)
|
|
var i = attrs.length
|
|
var dirs = []
|
|
var attr, attrName, dir, dirName, dirDef
|
|
while (i--) {
|
|
attr = attrs[i]
|
|
attrName = attr.name
|
|
if (attrName.indexOf(config.prefix) === 0) {
|
|
dirName = attrName.slice(config.prefix.length)
|
|
if (
|
|
asParent &&
|
|
(dirName === 'with' || dirName === 'ref')
|
|
) {
|
|
continue
|
|
}
|
|
dirDef = options.directives[dirName]
|
|
_.assertAsset(dirDef, 'directive', dirName)
|
|
if (dirDef) {
|
|
dirs.push({
|
|
name: dirName,
|
|
descriptors: dirParser.parse(attr.value),
|
|
def: dirDef
|
|
})
|
|
}
|
|
} else if (config.interpolate) {
|
|
dir = collectAttrDirective(el, attrName, attr.value,
|
|
options)
|
|
if (dir) {
|
|
dirs.push(dir)
|
|
}
|
|
}
|
|
}
|
|
// sort by priority, LOW to HIGH
|
|
dirs.sort(directiveComparator)
|
|
return dirs
|
|
}
|
|
|
|
/**
|
|
* Check an attribute for potential dynamic bindings,
|
|
* and return a directive object.
|
|
*
|
|
* @param {Element} el
|
|
* @param {String} name
|
|
* @param {String} value
|
|
* @param {Object} options
|
|
* @return {Object}
|
|
*/
|
|
|
|
function collectAttrDirective (el, name, value, options) {
|
|
var tokens = textParser.parse(value)
|
|
if (tokens) {
|
|
var def = options.directives.attr
|
|
var i = tokens.length
|
|
var allOneTime = true
|
|
while (i--) {
|
|
var token = tokens[i]
|
|
if (token.tag && !token.oneTime) {
|
|
allOneTime = false
|
|
}
|
|
}
|
|
return {
|
|
def: def,
|
|
_link: allOneTime
|
|
? function (vm, el) {
|
|
el.setAttribute(name, vm.$interpolate(value))
|
|
}
|
|
: function (vm, el) {
|
|
var value = textParser.tokensToExp(tokens, vm)
|
|
var desc = dirParser.parse(name + ':' + value)[0]
|
|
vm._bindDir('attr', el, desc, def)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Directive priority sort comparator
|
|
*
|
|
* @param {Object} a
|
|
* @param {Object} b
|
|
*/
|
|
|
|
function directiveComparator (a, b) {
|
|
a = a.def.priority || 0
|
|
b = b.def.priority || 0
|
|
return a > b ? 1 : -1
|
|
}
|
|
|
|
/***/ },
|
|
/* 47 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var templateParser = __webpack_require__(51)
|
|
|
|
/**
|
|
* Process an element or a DocumentFragment based on a
|
|
* instance option object. This allows us to transclude
|
|
* a template node/fragment before the instance is created,
|
|
* so the processed fragment can then be cloned and reused
|
|
* in v-repeat.
|
|
*
|
|
* @param {Element} el
|
|
* @param {Object} options
|
|
* @return {Element|DocumentFragment}
|
|
*/
|
|
|
|
module.exports = function transclude (el, options) {
|
|
// for template tags, what we want is its content as
|
|
// a documentFragment (for block instances)
|
|
if (el.tagName === 'TEMPLATE') {
|
|
el = templateParser.parse(el)
|
|
}
|
|
if (options && options.template) {
|
|
el = transcludeTemplate(el, options)
|
|
}
|
|
if (el instanceof DocumentFragment) {
|
|
_.prepend(document.createComment('v-start'), el)
|
|
el.appendChild(document.createComment('v-end'))
|
|
}
|
|
return el
|
|
}
|
|
|
|
/**
|
|
* Process the template option.
|
|
* If the replace option is true this will swap the $el.
|
|
*
|
|
* @param {Element} el
|
|
* @param {Object} options
|
|
* @return {Element|DocumentFragment}
|
|
*/
|
|
|
|
function transcludeTemplate (el, options) {
|
|
var template = options.template
|
|
var frag = templateParser.parse(template, true)
|
|
if (!frag) {
|
|
_.warn('Invalid template option: ' + template)
|
|
} else {
|
|
collectRawContent(el)
|
|
if (options.replace) {
|
|
if (frag.childNodes.length > 1) {
|
|
transcludeContent(frag)
|
|
return frag
|
|
} else {
|
|
var replacer = frag.firstChild
|
|
_.copyAttributes(el, replacer)
|
|
transcludeContent(replacer)
|
|
return replacer
|
|
}
|
|
} else {
|
|
el.appendChild(frag)
|
|
transcludeContent(el)
|
|
return el
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Collect raw content inside $el before they are
|
|
* replaced by template content.
|
|
*/
|
|
|
|
var rawContent
|
|
function collectRawContent (el) {
|
|
var child
|
|
rawContent = null
|
|
if (el.hasChildNodes()) {
|
|
rawContent = document.createElement('div')
|
|
/* jshint boss:true */
|
|
while (child = el.firstChild) {
|
|
rawContent.appendChild(child)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resolve <content> insertion points mimicking the behavior
|
|
* of the Shadow DOM spec:
|
|
*
|
|
* http://w3c.github.io/webcomponents/spec/shadow/#insertion-points
|
|
*
|
|
* @param {Element|DocumentFragment} el
|
|
*/
|
|
|
|
function transcludeContent (el) {
|
|
var outlets = getOutlets(el)
|
|
var i = outlets.length
|
|
if (!i) return
|
|
var outlet, select, selected, j, main
|
|
// first pass, collect corresponding content
|
|
// for each outlet.
|
|
while (i--) {
|
|
outlet = outlets[i]
|
|
if (rawContent) {
|
|
select = outlet.getAttribute('select')
|
|
if (select) { // select content
|
|
selected = rawContent.querySelectorAll(select)
|
|
outlet.content = _.toArray(
|
|
selected.length
|
|
? selected
|
|
: outlet.childNodes
|
|
)
|
|
} else { // default content
|
|
main = outlet
|
|
}
|
|
} else { // fallback content
|
|
outlet.content = _.toArray(outlet.childNodes)
|
|
}
|
|
}
|
|
// second pass, actually insert the contents
|
|
for (i = 0, j = outlets.length; i < j; i++) {
|
|
outlet = outlets[i]
|
|
if (outlet !== main) {
|
|
insertContentAt(outlet, outlet.content)
|
|
}
|
|
}
|
|
// finally insert the main content
|
|
if (main) {
|
|
insertContentAt(main, _.toArray(rawContent.childNodes))
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get <content> outlets from the element/list
|
|
*
|
|
* @param {Element|Array} el
|
|
* @return {Array}
|
|
*/
|
|
|
|
var concat = [].concat
|
|
function getOutlets (el) {
|
|
return _.isArray(el)
|
|
? concat.apply([], el.map(getOutlets))
|
|
: el.querySelectorAll
|
|
? _.toArray(el.querySelectorAll('content'))
|
|
: []
|
|
}
|
|
|
|
/**
|
|
* Insert an array of nodes at outlet,
|
|
* then remove the outlet.
|
|
*
|
|
* @param {Element} outlet
|
|
* @param {Array} contents
|
|
*/
|
|
|
|
function insertContentAt (outlet, contents) {
|
|
// not using util DOM methods here because
|
|
// parentNode can be cached
|
|
var parent = outlet.parentNode
|
|
for (var i = 0, j = contents.length; i < j; i++) {
|
|
parent.insertBefore(contents[i], outlet)
|
|
}
|
|
parent.removeChild(outlet)
|
|
}
|
|
|
|
/***/ },
|
|
/* 48 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
|
|
var handlers = {
|
|
_default: __webpack_require__(55),
|
|
radio: __webpack_require__(56),
|
|
select: __webpack_require__(57),
|
|
checkbox: __webpack_require__(58)
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
priority: 800,
|
|
twoWay: true,
|
|
handlers: handlers,
|
|
|
|
/**
|
|
* Possible elements:
|
|
* <select>
|
|
* <textarea>
|
|
* <input type="*">
|
|
* - text
|
|
* - checkbox
|
|
* - radio
|
|
* - number
|
|
* - TODO: more types may be supplied as a plugin
|
|
*/
|
|
|
|
bind: function () {
|
|
// friendly warning...
|
|
var filters = this.filters
|
|
if (filters && filters.read && !filters.write) {
|
|
_.warn(
|
|
'It seems you are using a read-only filter with ' +
|
|
'v-model. You might want to use a two-way filter ' +
|
|
'to ensure correct behavior.'
|
|
)
|
|
}
|
|
var el = this.el
|
|
var tag = el.tagName
|
|
var handler
|
|
if (tag === 'INPUT') {
|
|
handler = handlers[el.type] || handlers._default
|
|
} else if (tag === 'SELECT') {
|
|
handler = handlers.select
|
|
} else if (tag === 'TEXTAREA') {
|
|
handler = handlers._default
|
|
} else {
|
|
_.warn("v-model doesn't support element type: " + tag)
|
|
return
|
|
}
|
|
handler.bind.call(this)
|
|
this.update = handler.update
|
|
this.unbind = handler.unbind
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 49 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var config = __webpack_require__(20)
|
|
var Binding = __webpack_require__(39)
|
|
var arrayMethods = __webpack_require__(59)
|
|
var arrayKeys = Object.getOwnPropertyNames(arrayMethods)
|
|
__webpack_require__(60)
|
|
|
|
var uid = 0
|
|
|
|
/**
|
|
* Type enums
|
|
*/
|
|
|
|
var ARRAY = 0
|
|
var OBJECT = 1
|
|
|
|
/**
|
|
* Augment an target Object or Array by intercepting
|
|
* the prototype chain using __proto__
|
|
*
|
|
* @param {Object|Array} target
|
|
* @param {Object} proto
|
|
*/
|
|
|
|
function protoAugment (target, src) {
|
|
target.__proto__ = src
|
|
}
|
|
|
|
/**
|
|
* Augment an target Object or Array by defining
|
|
* hidden properties.
|
|
*
|
|
* @param {Object|Array} target
|
|
* @param {Object} proto
|
|
*/
|
|
|
|
function copyAugment (target, src, keys) {
|
|
var i = keys.length
|
|
var key
|
|
while (i--) {
|
|
key = keys[i]
|
|
_.define(target, key, src[key])
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Observer class that are attached to each observed
|
|
* object. Once attached, the observer converts target
|
|
* object's property keys into getter/setters that
|
|
* collect dependencies and dispatches updates.
|
|
*
|
|
* @param {Array|Object} value
|
|
* @param {Number} type
|
|
* @constructor
|
|
*/
|
|
|
|
function Observer (value, type) {
|
|
this.id = ++uid
|
|
this.value = value
|
|
this.active = true
|
|
this.bindings = []
|
|
_.define(value, '__ob__', this)
|
|
if (type === ARRAY) {
|
|
var augment = config.proto && _.hasProto
|
|
? protoAugment
|
|
: copyAugment
|
|
augment(value, arrayMethods, arrayKeys)
|
|
this.observeArray(value)
|
|
} else if (type === OBJECT) {
|
|
this.walk(value)
|
|
}
|
|
}
|
|
|
|
Observer.target = null
|
|
|
|
var p = Observer.prototype
|
|
|
|
/**
|
|
* Attempt to create an observer instance for a value,
|
|
* returns the new observer if successfully observed,
|
|
* or the existing observer if the value already has one.
|
|
*
|
|
* @param {*} value
|
|
* @return {Observer|undefined}
|
|
* @static
|
|
*/
|
|
|
|
Observer.create = function (value) {
|
|
if (
|
|
value &&
|
|
value.hasOwnProperty('__ob__') &&
|
|
value.__ob__ instanceof Observer
|
|
) {
|
|
return value.__ob__
|
|
} else if (_.isArray(value)) {
|
|
return new Observer(value, ARRAY)
|
|
} else if (
|
|
_.isPlainObject(value) &&
|
|
!value._isVue // avoid Vue instance
|
|
) {
|
|
return new Observer(value, OBJECT)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Walk through each property and convert them into
|
|
* getter/setters. This method should only be called when
|
|
* value type is Object. Properties prefixed with `$` or `_`
|
|
* and accessor properties are ignored.
|
|
*
|
|
* @param {Object} obj
|
|
*/
|
|
|
|
p.walk = function (obj) {
|
|
var keys = Object.keys(obj)
|
|
var i = keys.length
|
|
var key, prefix
|
|
while (i--) {
|
|
key = keys[i]
|
|
prefix = key.charCodeAt(0)
|
|
if (prefix !== 0x24 && prefix !== 0x5F) { // skip $ or _
|
|
this.convert(key, obj[key])
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Try to carete an observer for a child value,
|
|
* and if value is array, link binding to the array.
|
|
*
|
|
* @param {*} val
|
|
* @return {Binding|undefined}
|
|
*/
|
|
|
|
p.observe = function (val) {
|
|
return Observer.create(val)
|
|
}
|
|
|
|
/**
|
|
* Observe a list of Array items.
|
|
*
|
|
* @param {Array} items
|
|
*/
|
|
|
|
p.observeArray = function (items) {
|
|
var i = items.length
|
|
while (i--) {
|
|
this.observe(items[i])
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convert a property into getter/setter so we can emit
|
|
* the events when the property is accessed/changed.
|
|
*
|
|
* @param {String} key
|
|
* @param {*} val
|
|
*/
|
|
|
|
p.convert = function (key, val) {
|
|
var ob = this
|
|
var childOb = ob.observe(val)
|
|
var binding = new Binding()
|
|
if (childOb) {
|
|
childOb.bindings.push(binding)
|
|
}
|
|
Object.defineProperty(ob.value, key, {
|
|
enumerable: true,
|
|
configurable: true,
|
|
get: function () {
|
|
// Observer.target is a watcher whose getter is
|
|
// currently being evaluated.
|
|
if (ob.active && Observer.target) {
|
|
Observer.target.addDep(binding)
|
|
}
|
|
return val
|
|
},
|
|
set: function (newVal) {
|
|
if (newVal === val) return
|
|
// remove binding from old value
|
|
var oldChildOb = val && val.__ob__
|
|
if (oldChildOb) {
|
|
var oldBindings = oldChildOb.bindings
|
|
oldBindings.splice(oldBindings.indexOf(binding), 1)
|
|
}
|
|
val = newVal
|
|
// add binding to new value
|
|
var newChildOb = ob.observe(newVal)
|
|
if (newChildOb) {
|
|
newChildOb.bindings.push(binding)
|
|
}
|
|
binding.notify()
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Notify change on all self bindings on an observer.
|
|
* This is called when a mutable value mutates. e.g.
|
|
* when an Array's mutating methods are called, or an
|
|
* Object's $add/$delete are called.
|
|
*/
|
|
|
|
p.notify = function () {
|
|
var bindings = this.bindings
|
|
for (var i = 0, l = bindings.length; i < l; i++) {
|
|
bindings[i].notify()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add an owner vm, so that when $add/$delete mutations
|
|
* happen we can notify owner vms to proxy the keys and
|
|
* digest the watchers. This is only called when the object
|
|
* is observed as an instance's root $data.
|
|
*
|
|
* @param {Vue} vm
|
|
*/
|
|
|
|
p.addVm = function (vm) {
|
|
(this.vms = this.vms || []).push(vm)
|
|
}
|
|
|
|
/**
|
|
* Remove an owner vm. This is called when the object is
|
|
* swapped out as an instance's $data object.
|
|
*
|
|
* @param {Vue} vm
|
|
*/
|
|
|
|
p.removeVm = function (vm) {
|
|
this.vms.splice(this.vms.indexOf(vm), 1)
|
|
}
|
|
|
|
module.exports = Observer
|
|
|
|
|
|
/***/ },
|
|
/* 50 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
|
|
/**
|
|
* The Batcher maintains a job queue to be run
|
|
* async on the next event loop.
|
|
*/
|
|
|
|
function Batcher () {
|
|
this.reset()
|
|
}
|
|
|
|
var p = Batcher.prototype
|
|
|
|
/**
|
|
* Push a job into the job queue.
|
|
* Jobs with duplicate IDs will be skipped unless it's
|
|
* pushed when the queue is being flushed.
|
|
*
|
|
* @param {Object} job
|
|
* properties:
|
|
* - {String|Number} id
|
|
* - {Function} run
|
|
*/
|
|
|
|
p.push = function (job) {
|
|
if (!job.id || !this.has[job.id] || this.flushing) {
|
|
this.queue.push(job)
|
|
this.has[job.id] = job
|
|
if (!this.waiting) {
|
|
this.waiting = true
|
|
_.nextTick(this.flush, this)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Flush the queue and run the jobs.
|
|
* Will call a preFlush hook if has one.
|
|
*/
|
|
|
|
p.flush = function () {
|
|
this.flushing = true
|
|
// do not cache length because more jobs might be pushed
|
|
// as we run existing jobs
|
|
for (var i = 0; i < this.queue.length; i++) {
|
|
var job = this.queue[i]
|
|
if (!job.cancelled) {
|
|
job.run()
|
|
}
|
|
}
|
|
this.reset()
|
|
}
|
|
|
|
/**
|
|
* Reset the batcher's state.
|
|
*/
|
|
|
|
p.reset = function () {
|
|
this.has = {}
|
|
this.queue = []
|
|
this.waiting = false
|
|
this.flushing = false
|
|
}
|
|
|
|
module.exports = Batcher
|
|
|
|
/***/ },
|
|
/* 51 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var Cache = __webpack_require__(52)
|
|
var templateCache = new Cache(100)
|
|
|
|
/**
|
|
* Test for the presence of the Safari template cloning bug
|
|
* https://bugs.webkit.org/show_bug.cgi?id=137755
|
|
*/
|
|
|
|
var hasBrokenTemplate = _.inBrowser
|
|
? (function () {
|
|
var a = document.createElement('div')
|
|
a.innerHTML = '<template>1</template>'
|
|
return !a.cloneNode(true).firstChild.innerHTML
|
|
})()
|
|
: false
|
|
|
|
var map = {
|
|
_default : [0, '', ''],
|
|
legend : [1, '<fieldset>', '</fieldset>'],
|
|
tr : [2, '<table><tbody>', '</tbody></table>'],
|
|
col : [
|
|
2,
|
|
'<table><tbody></tbody><colgroup>',
|
|
'</colgroup></table>'
|
|
]
|
|
}
|
|
|
|
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.g =
|
|
map.defs =
|
|
map.symbol =
|
|
map.use =
|
|
map.image =
|
|
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" ' +
|
|
'xmlns:xlink="http://www.w3.org/1999/xlink" ' +
|
|
'xmlns:ev="http://www.w3.org/2001/xml-events"' +
|
|
'version="1.1">',
|
|
'</svg>'
|
|
]
|
|
|
|
var TAG_RE = /<([\w:]+)/
|
|
|
|
/**
|
|
* Convert a string template to a DocumentFragment.
|
|
* Determines correct wrapping by tag types. Wrapping
|
|
* strategy found in jQuery & component/domify.
|
|
*
|
|
* @param {String} templateString
|
|
* @return {DocumentFragment}
|
|
*/
|
|
|
|
function stringToFragment (templateString) {
|
|
// try a cache hit first
|
|
var hit = templateCache.get(templateString)
|
|
if (hit) {
|
|
return hit
|
|
}
|
|
|
|
var frag = document.createDocumentFragment()
|
|
var tagMatch = TAG_RE.exec(templateString)
|
|
|
|
if (!tagMatch) {
|
|
// text only, return a single text node.
|
|
frag.appendChild(
|
|
document.createTextNode(templateString)
|
|
)
|
|
} else {
|
|
|
|
var tag = tagMatch[1]
|
|
var wrap = map[tag] || map._default
|
|
var depth = wrap[0]
|
|
var prefix = wrap[1]
|
|
var suffix = wrap[2]
|
|
var node = document.createElement('div')
|
|
|
|
node.innerHTML = prefix + templateString.trim() + suffix
|
|
while (depth--) {
|
|
node = node.lastChild
|
|
}
|
|
|
|
var child
|
|
/* jshint boss:true */
|
|
while (child = node.firstChild) {
|
|
frag.appendChild(child)
|
|
}
|
|
}
|
|
|
|
templateCache.put(templateString, frag)
|
|
return frag
|
|
}
|
|
|
|
/**
|
|
* Convert a template node to a DocumentFragment.
|
|
*
|
|
* @param {Node} node
|
|
* @return {DocumentFragment}
|
|
*/
|
|
|
|
function nodeToFragment (node) {
|
|
var tag = node.tagName
|
|
// if its a template tag and the browser supports it,
|
|
// its content is already a document fragment.
|
|
if (
|
|
tag === 'TEMPLATE' &&
|
|
node.content instanceof DocumentFragment
|
|
) {
|
|
return node.content
|
|
}
|
|
return tag === 'SCRIPT'
|
|
? stringToFragment(node.textContent)
|
|
: stringToFragment(node.innerHTML)
|
|
}
|
|
|
|
/**
|
|
* Deal with Safari cloning nested <template> bug by
|
|
* manually cloning all template instances.
|
|
*
|
|
* @param {Element|DocumentFragment} node
|
|
* @return {Element|DocumentFragment}
|
|
*/
|
|
|
|
exports.clone = function (node) {
|
|
var res = node.cloneNode(true)
|
|
/* istanbul ignore if */
|
|
if (hasBrokenTemplate) {
|
|
var templates = node.querySelectorAll('template')
|
|
if (templates.length) {
|
|
var cloned = res.querySelectorAll('template')
|
|
var i = cloned.length
|
|
while (i--) {
|
|
cloned[i].parentNode.replaceChild(
|
|
templates[i].cloneNode(true),
|
|
cloned[i]
|
|
)
|
|
}
|
|
}
|
|
}
|
|
return res
|
|
}
|
|
|
|
/**
|
|
* Process the template option and normalizes it into a
|
|
* a DocumentFragment that can be used as a partial or a
|
|
* instance template.
|
|
*
|
|
* @param {*} template
|
|
* Possible values include:
|
|
* - DocumentFragment object
|
|
* - Node object of type Template
|
|
* - id selector: '#some-template-id'
|
|
* - template string: '<div><span>{{msg}}</span></div>'
|
|
* @param {Boolean} clone
|
|
* @return {DocumentFragment|undefined}
|
|
*/
|
|
|
|
exports.parse = function (template, clone) {
|
|
var node, frag
|
|
|
|
// if the template is already a document fragment,
|
|
// do nothing
|
|
if (template instanceof DocumentFragment) {
|
|
return clone
|
|
? template.cloneNode(true)
|
|
: template
|
|
}
|
|
|
|
if (typeof template === 'string') {
|
|
// id selector
|
|
if (template.charAt(0) === '#') {
|
|
// id selector can be cached too
|
|
frag = templateCache.get(template)
|
|
if (!frag) {
|
|
node = document.getElementById(template.slice(1))
|
|
if (node) {
|
|
frag = nodeToFragment(node)
|
|
// save selector to cache
|
|
templateCache.put(template, frag)
|
|
}
|
|
}
|
|
} else {
|
|
// normal string template
|
|
frag = stringToFragment(template)
|
|
}
|
|
} else if (template.nodeType) {
|
|
// a direct node
|
|
frag = nodeToFragment(template)
|
|
}
|
|
|
|
return frag && clone
|
|
? exports.clone(frag)
|
|
: frag
|
|
}
|
|
|
|
/***/ },
|
|
/* 52 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* A doubly linked list-based Least Recently Used (LRU)
|
|
* cache. Will keep most recently used items while
|
|
* discarding least recently used items when its limit is
|
|
* reached. This is a bare-bone version of
|
|
* Rasmus Andersson's js-lru:
|
|
*
|
|
* https://github.com/rsms/js-lru
|
|
*
|
|
* @param {Number} limit
|
|
* @constructor
|
|
*/
|
|
|
|
function Cache (limit) {
|
|
this.size = 0
|
|
this.limit = limit
|
|
this.head = this.tail = undefined
|
|
this._keymap = {}
|
|
}
|
|
|
|
var p = Cache.prototype
|
|
|
|
/**
|
|
* Put <value> into the cache associated with <key>.
|
|
* Returns the entry which was removed to make room for
|
|
* the new entry. Otherwise undefined is returned.
|
|
* (i.e. if there was enough room already).
|
|
*
|
|
* @param {String} key
|
|
* @param {*} value
|
|
* @return {Entry|undefined}
|
|
*/
|
|
|
|
p.put = function (key, value) {
|
|
var entry = {
|
|
key:key,
|
|
value:value
|
|
}
|
|
this._keymap[key] = entry
|
|
if (this.tail) {
|
|
this.tail.newer = entry
|
|
entry.older = this.tail
|
|
} else {
|
|
this.head = entry
|
|
}
|
|
this.tail = entry
|
|
if (this.size === this.limit) {
|
|
return this.shift()
|
|
} else {
|
|
this.size++
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Purge the least recently used (oldest) entry from the
|
|
* cache. Returns the removed entry or undefined if the
|
|
* cache was empty.
|
|
*/
|
|
|
|
p.shift = function () {
|
|
var entry = this.head
|
|
if (entry) {
|
|
this.head = this.head.newer
|
|
this.head.older = undefined
|
|
entry.newer = entry.older = undefined
|
|
this._keymap[entry.key] = undefined
|
|
}
|
|
return entry
|
|
}
|
|
|
|
/**
|
|
* Get and register recent use of <key>. Returns the value
|
|
* associated with <key> or undefined if not in cache.
|
|
*
|
|
* @param {String} key
|
|
* @param {Boolean} returnEntry
|
|
* @return {Entry|*}
|
|
*/
|
|
|
|
p.get = function (key, returnEntry) {
|
|
var entry = this._keymap[key]
|
|
if (entry === undefined) return
|
|
if (entry === this.tail) {
|
|
return returnEntry
|
|
? entry
|
|
: entry.value
|
|
}
|
|
// HEAD--------------TAIL
|
|
// <.older .newer>
|
|
// <--- add direction --
|
|
// A B C <D> E
|
|
if (entry.newer) {
|
|
if (entry === this.head) {
|
|
this.head = entry.newer
|
|
}
|
|
entry.newer.older = entry.older // C <-- E.
|
|
}
|
|
if (entry.older) {
|
|
entry.older.newer = entry.newer // C. --> E
|
|
}
|
|
entry.newer = undefined // D --x
|
|
entry.older = this.tail // D. --> E
|
|
if (this.tail) {
|
|
this.tail.newer = entry // E. <-- D
|
|
}
|
|
this.tail = entry
|
|
return returnEntry
|
|
? entry
|
|
: entry.value
|
|
}
|
|
|
|
module.exports = Cache
|
|
|
|
/***/ },
|
|
/* 53 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var addClass = _.addClass
|
|
var removeClass = _.removeClass
|
|
var transDurationProp = _.transitionProp + 'Duration'
|
|
var animDurationProp = _.animationProp + 'Duration'
|
|
|
|
var queue = []
|
|
var queued = false
|
|
|
|
/**
|
|
* Push a job into the transition queue, which is to be
|
|
* executed on next frame.
|
|
*
|
|
* @param {Element} el - target element
|
|
* @param {Number} dir - 1: enter, -1: leave
|
|
* @param {Function} op - the actual dom operation
|
|
* @param {String} cls - the className to remove when the
|
|
* transition is done.
|
|
* @param {Function} [cb] - user supplied callback.
|
|
*/
|
|
|
|
function push (el, dir, op, cls, cb) {
|
|
queue.push({
|
|
el : el,
|
|
dir : dir,
|
|
cb : cb,
|
|
cls : cls,
|
|
op : op
|
|
})
|
|
if (!queued) {
|
|
queued = true
|
|
_.nextTick(flush)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Flush the queue, and do one forced reflow before
|
|
* triggering transitions.
|
|
*/
|
|
|
|
function flush () {
|
|
/* jshint unused: false */
|
|
var f = document.documentElement.offsetHeight
|
|
queue.forEach(run)
|
|
queue = []
|
|
queued = false
|
|
}
|
|
|
|
/**
|
|
* Run a transition job.
|
|
*
|
|
* @param {Object} job
|
|
*/
|
|
|
|
function run (job) {
|
|
|
|
var el = job.el
|
|
var data = el.__v_trans
|
|
var cls = job.cls
|
|
var cb = job.cb
|
|
var op = job.op
|
|
var transitionType = getTransitionType(el, data, cls)
|
|
|
|
if (job.dir > 0) { // ENTER
|
|
if (transitionType === 1) {
|
|
// trigger transition by removing enter class
|
|
removeClass(el, cls)
|
|
// only need to listen for transitionend if there's
|
|
// a user callback
|
|
if (cb) setupTransitionCb(_.transitionEndEvent)
|
|
} else if (transitionType === 2) {
|
|
// animations are triggered when class is added
|
|
// so we just listen for animationend to remove it.
|
|
setupTransitionCb(_.animationEndEvent, function () {
|
|
removeClass(el, cls)
|
|
})
|
|
} else {
|
|
// no transition applicable
|
|
removeClass(el, cls)
|
|
if (cb) cb()
|
|
}
|
|
} else { // LEAVE
|
|
if (transitionType) {
|
|
// leave transitions/animations are both triggered
|
|
// by adding the class, just remove it on end event.
|
|
var event = transitionType === 1
|
|
? _.transitionEndEvent
|
|
: _.animationEndEvent
|
|
setupTransitionCb(event, function () {
|
|
op()
|
|
removeClass(el, cls)
|
|
})
|
|
} else {
|
|
op()
|
|
removeClass(el, cls)
|
|
if (cb) cb()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set up a transition end callback, store the callback
|
|
* on the element's __v_trans data object, so we can
|
|
* clean it up if another transition is triggered before
|
|
* the callback is fired.
|
|
*
|
|
* @param {String} event
|
|
* @param {Function} [cleanupFn]
|
|
*/
|
|
|
|
function setupTransitionCb (event, cleanupFn) {
|
|
data.event = event
|
|
var onEnd = data.callback = function transitionCb (e) {
|
|
if (e.target === el) {
|
|
_.off(el, event, onEnd)
|
|
data.event = data.callback = null
|
|
if (cleanupFn) cleanupFn()
|
|
if (cb) cb()
|
|
}
|
|
}
|
|
_.on(el, event, onEnd)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get an element's transition type based on the
|
|
* calculated styles
|
|
*
|
|
* @param {Element} el
|
|
* @param {Object} data
|
|
* @param {String} className
|
|
* @return {Number}
|
|
* 1 - transition
|
|
* 2 - animation
|
|
*/
|
|
|
|
function getTransitionType (el, data, className) {
|
|
var type = data.cache && data.cache[className]
|
|
if (type) return type
|
|
var inlineStyles = el.style
|
|
var computedStyles = window.getComputedStyle(el)
|
|
var transDuration =
|
|
inlineStyles[transDurationProp] ||
|
|
computedStyles[transDurationProp]
|
|
if (transDuration && transDuration !== '0s') {
|
|
type = 1
|
|
} else {
|
|
var animDuration =
|
|
inlineStyles[animDurationProp] ||
|
|
computedStyles[animDurationProp]
|
|
if (animDuration && animDuration !== '0s') {
|
|
type = 2
|
|
}
|
|
}
|
|
if (type) {
|
|
if (!data.cache) data.cache = {}
|
|
data.cache[className] = type
|
|
}
|
|
return type
|
|
}
|
|
|
|
/**
|
|
* Apply CSS transition to an element.
|
|
*
|
|
* @param {Element} el
|
|
* @param {Number} direction - 1: enter, -1: leave
|
|
* @param {Function} op - the actual DOM operation
|
|
* @param {Object} data - target element's transition data
|
|
*/
|
|
|
|
module.exports = function (el, direction, op, data, cb) {
|
|
var prefix = data.id || 'v'
|
|
var enterClass = prefix + '-enter'
|
|
var leaveClass = prefix + '-leave'
|
|
// clean up potential previous unfinished transition
|
|
if (data.callback) {
|
|
_.off(el, data.event, data.callback)
|
|
removeClass(el, enterClass)
|
|
removeClass(el, leaveClass)
|
|
data.event = data.callback = null
|
|
}
|
|
if (direction > 0) { // enter
|
|
addClass(el, enterClass)
|
|
op()
|
|
push(el, direction, null, enterClass, cb)
|
|
} else { // leave
|
|
addClass(el, leaveClass)
|
|
push(el, direction, op, leaveClass, cb)
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 54 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Apply JavaScript enter/leave functions.
|
|
*
|
|
* @param {Element} el
|
|
* @param {Number} direction - 1: enter, -1: leave
|
|
* @param {Function} op - the actual DOM operation
|
|
* @param {Object} data - target element's transition data
|
|
* @param {Object} def - transition definition object
|
|
* @param {Vue} vm - the owner vm of the element
|
|
* @param {Function} [cb]
|
|
*/
|
|
|
|
module.exports = function (el, direction, op, data, def, vm, cb) {
|
|
if (data.cancel) {
|
|
data.cancel()
|
|
data.cancel = null
|
|
}
|
|
if (direction > 0) { // enter
|
|
if (def.beforeEnter) {
|
|
def.beforeEnter.call(vm, el)
|
|
}
|
|
op()
|
|
if (def.enter) {
|
|
data.cancel = def.enter.call(vm, el, function () {
|
|
data.cancel = null
|
|
if (cb) cb()
|
|
})
|
|
} else if (cb) {
|
|
cb()
|
|
}
|
|
} else { // leave
|
|
if (def.leave) {
|
|
data.cancel = def.leave.call(vm, el, function () {
|
|
data.cancel = null
|
|
op()
|
|
if (cb) cb()
|
|
})
|
|
} else {
|
|
op()
|
|
if (cb) cb()
|
|
}
|
|
}
|
|
}
|
|
|
|
/***/ },
|
|
/* 55 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
|
|
module.exports = {
|
|
|
|
bind: function () {
|
|
var self = this
|
|
var el = this.el
|
|
|
|
// check params
|
|
// - lazy: update model on "change" instead of "input"
|
|
var lazy = el.hasAttribute('lazy')
|
|
if (lazy) {
|
|
el.removeAttribute('lazy')
|
|
}
|
|
// - number: cast value into number when updating model.
|
|
var number =
|
|
el.hasAttribute('number') ||
|
|
el.type === 'number'
|
|
if (number) {
|
|
el.removeAttribute('number')
|
|
}
|
|
|
|
// handle composition events.
|
|
// http://blog.evanyou.me/2014/01/03/composition-event/
|
|
var cpLocked = false
|
|
this.cpLock = function () {
|
|
cpLocked = true
|
|
}
|
|
this.cpUnlock = function () {
|
|
cpLocked = false
|
|
// in IE11 the "compositionend" event fires AFTER
|
|
// the "input" event, so the input handler is blocked
|
|
// at the end... have to call it here.
|
|
set()
|
|
}
|
|
_.on(el,'compositionstart', this.cpLock)
|
|
_.on(el,'compositionend', this.cpUnlock)
|
|
|
|
// shared setter
|
|
function set () {
|
|
self.set(
|
|
number ? _.toNumber(el.value) : el.value,
|
|
true
|
|
)
|
|
}
|
|
|
|
// if the directive has filters, we need to
|
|
// record cursor position and restore it after updating
|
|
// the input with the filtered value.
|
|
this.listener = function textInputListener () {
|
|
if (cpLocked) return
|
|
var charsOffset
|
|
// some HTML5 input types throw error here
|
|
try {
|
|
// record how many chars from the end of input
|
|
// the cursor was at
|
|
charsOffset = el.value.length - el.selectionStart
|
|
} catch (e) {}
|
|
set()
|
|
// force a value update, because in
|
|
// certain cases the write filters output the same
|
|
// result for different input values, and the Observer
|
|
// set events won't be triggered.
|
|
_.nextTick(function () {
|
|
var newVal = self._watcher.value
|
|
self.update(newVal)
|
|
if (charsOffset != null) {
|
|
var cursorPos =
|
|
_.toString(newVal).length - charsOffset
|
|
el.setSelectionRange(cursorPos, cursorPos)
|
|
}
|
|
})
|
|
}
|
|
this.event = lazy ? 'change' : 'input'
|
|
_.on(el, this.event, this.listener)
|
|
|
|
// IE9 doesn't fire input event on backspace/del/cut
|
|
if (!lazy && _.isIE9) {
|
|
this.onCut = function () {
|
|
_.nextTick(self.listener)
|
|
}
|
|
this.onDel = function (e) {
|
|
if (e.keyCode === 46 || e.keyCode === 8) {
|
|
self.listener()
|
|
}
|
|
}
|
|
_.on(el, 'cut', this.onCut)
|
|
_.on(el, 'keyup', this.onDel)
|
|
}
|
|
|
|
// set initial value if present
|
|
if (
|
|
el.hasAttribute('value') ||
|
|
(el.tagName === 'TEXTAREA' && el.value.trim())
|
|
) {
|
|
this._initValue = number
|
|
? _.toNumber(el.value)
|
|
: el.value
|
|
}
|
|
},
|
|
|
|
update: function (value) {
|
|
this.el.value = _.toString(value)
|
|
},
|
|
|
|
unbind: function () {
|
|
var el = this.el
|
|
_.off(el, this.event, this.listener)
|
|
_.off(el,'compositionstart', this.cpLock)
|
|
_.off(el,'compositionend', this.cpUnlock)
|
|
if (this.onCut) {
|
|
_.off(el,'cut', this.onCut)
|
|
_.off(el,'keyup', this.onDel)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 56 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
|
|
module.exports = {
|
|
|
|
bind: function () {
|
|
var self = this
|
|
var el = this.el
|
|
this.listener = function () {
|
|
self.set(el.value, true)
|
|
}
|
|
_.on(el, 'change', this.listener)
|
|
if (el.checked) {
|
|
this._initValue = el.value
|
|
}
|
|
},
|
|
|
|
update: function (value) {
|
|
/* jshint eqeqeq: false */
|
|
this.el.checked = value == this.el.value
|
|
},
|
|
|
|
unbind: function () {
|
|
_.off(this.el, 'change', this.listener)
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 57 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var Watcher = __webpack_require__(21)
|
|
|
|
module.exports = {
|
|
|
|
bind: function () {
|
|
var self = this
|
|
var el = this.el
|
|
// check options param
|
|
var optionsParam = el.getAttribute('options')
|
|
if (optionsParam) {
|
|
el.removeAttribute('options')
|
|
initOptions.call(this, optionsParam)
|
|
}
|
|
this.multiple = el.hasAttribute('multiple')
|
|
this.listener = function () {
|
|
var value = self.multiple
|
|
? getMultiValue(el)
|
|
: el.value
|
|
self.set(value, true)
|
|
}
|
|
_.on(el, 'change', this.listener)
|
|
checkInitialValue.call(this)
|
|
},
|
|
|
|
update: function (value) {
|
|
/* jshint eqeqeq: false */
|
|
var el = this.el
|
|
el.selectedIndex = -1
|
|
var multi = this.multiple && _.isArray(value)
|
|
var options = el.options
|
|
var i = options.length
|
|
var option
|
|
while (i--) {
|
|
option = options[i]
|
|
option.selected = multi
|
|
? indexOf(value, option.value) > -1
|
|
: value == option.value
|
|
}
|
|
},
|
|
|
|
unbind: function () {
|
|
_.off(this.el, 'change', this.listener)
|
|
if (this.optionWatcher) {
|
|
this.optionWatcher.teardown()
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Initialize the option list from the param.
|
|
*
|
|
* @param {String} expression
|
|
*/
|
|
|
|
function initOptions (expression) {
|
|
var self = this
|
|
function optionUpdateWatcher (value) {
|
|
if (_.isArray(value)) {
|
|
self.el.innerHTML = ''
|
|
buildOptions(self.el, value)
|
|
if (self._watcher) {
|
|
self.update(self._watcher.value)
|
|
}
|
|
} else {
|
|
_.warn('Invalid options value for v-model: ' + value)
|
|
}
|
|
}
|
|
this.optionWatcher = new Watcher(
|
|
this.vm,
|
|
expression,
|
|
optionUpdateWatcher
|
|
)
|
|
// update with initial value
|
|
optionUpdateWatcher(this.optionWatcher.value)
|
|
}
|
|
|
|
/**
|
|
* Build up option elements. IE9 doesn't create options
|
|
* when setting innerHTML on <select> elements, so we have
|
|
* to use DOM API here.
|
|
*
|
|
* @param {Element} parent - a <select> or an <optgroup>
|
|
* @param {Array} options
|
|
*/
|
|
|
|
function buildOptions (parent, options) {
|
|
var op, el
|
|
for (var i = 0, l = options.length; i < l; i++) {
|
|
op = options[i]
|
|
if (!op.options) {
|
|
el = document.createElement('option')
|
|
if (typeof op === 'string') {
|
|
el.text = el.value = op
|
|
} else {
|
|
el.text = op.text
|
|
el.value = op.value
|
|
}
|
|
} else {
|
|
el = document.createElement('optgroup')
|
|
el.label = op.label
|
|
buildOptions(el, op.options)
|
|
}
|
|
parent.appendChild(el)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check the initial value for selected options.
|
|
*/
|
|
|
|
function checkInitialValue () {
|
|
var initValue
|
|
var options = this.el.options
|
|
for (var i = 0, l = options.length; i < l; i++) {
|
|
if (options[i].hasAttribute('selected')) {
|
|
if (this.multiple) {
|
|
(initValue || (initValue = []))
|
|
.push(options[i].value)
|
|
} else {
|
|
initValue = options[i].value
|
|
}
|
|
}
|
|
}
|
|
if (initValue) {
|
|
this._initValue = initValue
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper to extract a value array for select[multiple]
|
|
*
|
|
* @param {SelectElement} el
|
|
* @return {Array}
|
|
*/
|
|
|
|
function getMultiValue (el) {
|
|
return Array.prototype.filter
|
|
.call(el.options, filterSelected)
|
|
.map(getOptionValue)
|
|
}
|
|
|
|
function filterSelected (op) {
|
|
return op.selected
|
|
}
|
|
|
|
function getOptionValue (op) {
|
|
return op.value || op.text
|
|
}
|
|
|
|
/**
|
|
* Native Array.indexOf uses strict equal, but in this
|
|
* case we need to match string/numbers with soft equal.
|
|
*
|
|
* @param {Array} arr
|
|
* @param {*} val
|
|
*/
|
|
|
|
function indexOf (arr, val) {
|
|
/* jshint eqeqeq: false */
|
|
var i = arr.length
|
|
while (i--) {
|
|
if (arr[i] == val) return i
|
|
}
|
|
return -1
|
|
}
|
|
|
|
/***/ },
|
|
/* 58 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
|
|
module.exports = {
|
|
|
|
bind: function () {
|
|
var self = this
|
|
var el = this.el
|
|
this.listener = function () {
|
|
self.set(el.checked, true)
|
|
}
|
|
_.on(el, 'change', this.listener)
|
|
if (el.checked) {
|
|
this._initValue = el.checked
|
|
}
|
|
},
|
|
|
|
update: function (value) {
|
|
this.el.checked = !!value
|
|
},
|
|
|
|
unbind: function () {
|
|
_.off(this.el, 'change', this.listener)
|
|
}
|
|
|
|
}
|
|
|
|
/***/ },
|
|
/* 59 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var arrayProto = Array.prototype
|
|
var arrayMethods = Object.create(arrayProto)
|
|
|
|
/**
|
|
* Intercept mutating methods and emit events
|
|
*/
|
|
|
|
;[
|
|
'push',
|
|
'pop',
|
|
'shift',
|
|
'unshift',
|
|
'splice',
|
|
'sort',
|
|
'reverse'
|
|
]
|
|
.forEach(function (method) {
|
|
// cache original method
|
|
var original = arrayProto[method]
|
|
_.define(arrayMethods, method, function mutator () {
|
|
// avoid leaking arguments:
|
|
// http://jsperf.com/closure-with-arguments
|
|
var i = arguments.length
|
|
var args = new Array(i)
|
|
while (i--) {
|
|
args[i] = arguments[i]
|
|
}
|
|
var result = original.apply(this, args)
|
|
var ob = this.__ob__
|
|
var inserted
|
|
switch (method) {
|
|
case 'push':
|
|
inserted = args
|
|
break
|
|
case 'unshift':
|
|
inserted = args
|
|
break
|
|
case 'splice':
|
|
inserted = args.slice(2)
|
|
break
|
|
}
|
|
if (inserted) ob.observeArray(inserted)
|
|
// notify change
|
|
ob.notify()
|
|
return result
|
|
})
|
|
})
|
|
|
|
/**
|
|
* Swap the element at the given index with a new value
|
|
* and emits corresponding event.
|
|
*
|
|
* @param {Number} index
|
|
* @param {*} val
|
|
* @return {*} - replaced element
|
|
*/
|
|
|
|
_.define(
|
|
arrayProto,
|
|
'$set',
|
|
function $set (index, val) {
|
|
if (index >= this.length) {
|
|
this.length = index + 1
|
|
}
|
|
return this.splice(index, 1, val)[0]
|
|
}
|
|
)
|
|
|
|
/**
|
|
* Convenience method to remove the element at given index.
|
|
*
|
|
* @param {Number} index
|
|
* @param {*} val
|
|
*/
|
|
|
|
_.define(
|
|
arrayProto,
|
|
'$remove',
|
|
function $remove (index) {
|
|
if (typeof index !== 'number') {
|
|
index = this.indexOf(index)
|
|
}
|
|
if (index > -1) {
|
|
return this.splice(index, 1)[0]
|
|
}
|
|
}
|
|
)
|
|
|
|
module.exports = arrayMethods
|
|
|
|
/***/ },
|
|
/* 60 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var _ = __webpack_require__(1)
|
|
var objProto = Object.prototype
|
|
|
|
/**
|
|
* Add a new property to an observed object
|
|
* and emits corresponding event
|
|
*
|
|
* @param {String} key
|
|
* @param {*} val
|
|
* @public
|
|
*/
|
|
|
|
_.define(
|
|
objProto,
|
|
'$add',
|
|
function $add (key, val) {
|
|
var ob = this.__ob__
|
|
if (!ob) {
|
|
this[key] = val
|
|
return
|
|
}
|
|
if (_.isReserved(key)) {
|
|
_.warn('Refused to $add reserved key: ' + key)
|
|
return
|
|
}
|
|
if (this.hasOwnProperty(key)) return
|
|
ob.convert(key, val)
|
|
if (ob.vms) {
|
|
var i = ob.vms.length
|
|
while (i--) {
|
|
var vm = ob.vms[i]
|
|
vm._proxy(key)
|
|
vm._digest()
|
|
}
|
|
} else {
|
|
ob.notify()
|
|
}
|
|
}
|
|
)
|
|
|
|
/**
|
|
* Deletes a property from an observed object
|
|
* and emits corresponding event
|
|
*
|
|
* @param {String} key
|
|
* @public
|
|
*/
|
|
|
|
_.define(
|
|
objProto,
|
|
'$delete',
|
|
function $delete (key) {
|
|
var ob = this.__ob__
|
|
if (!ob) {
|
|
delete this[key]
|
|
return
|
|
}
|
|
if (_.isReserved(key)) {
|
|
_.warn('Refused to $add reserved key: ' + key)
|
|
return
|
|
}
|
|
if (!this.hasOwnProperty(key)) return
|
|
delete this[key]
|
|
if (ob.vms) {
|
|
var i = ob.vms.length
|
|
while (i--) {
|
|
var vm = ob.vms[i]
|
|
vm._unproxy(key)
|
|
vm._digest()
|
|
}
|
|
} else {
|
|
ob.notify()
|
|
}
|
|
}
|
|
)
|
|
|
|
/***/ }
|
|
/******/ ])
|
|
});
|