/*! * Vue.js v2.0.0-rc.7 * (c) 2014-2016 Evan You * Released under the MIT License. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.Vue = factory()); }(this, (function () { 'use strict'; /* */ /** * Convert a value to a string that is actually rendered. */ function _toString (val) { return val == null ? '' : typeof val === 'object' ? JSON.stringify(val, null, 2) : String(val) } /** * Convert a input value to a number for persistence. * If the conversion fails, return original string. */ function toNumber (val) { var n = parseFloat(val, 10) return (n || n === 0) ? n : val } /** * Make a map and return a function for checking if a key * is in that map. */ function makeMap ( str, expectsLowerCase ) { var map = Object.create(null) var list = str.split(',') for (var i = 0; i < list.length; i++) { map[list[i]] = true } return expectsLowerCase ? function (val) { return map[val.toLowerCase()]; } : function (val) { return map[val]; } } /** * Check if a tag is a built-in tag. */ var isBuiltInTag = makeMap('slot,component', true) /** * Remove an item from an array */ function remove (arr, item) { if (arr.length) { var index = arr.indexOf(item) if (index > -1) { return arr.splice(index, 1) } } } /** * Check whether the object has the property. */ var hasOwnProperty = Object.prototype.hasOwnProperty function hasOwn (obj, key) { return hasOwnProperty.call(obj, key) } /** * Check if value is primitive */ function isPrimitive (value) { return typeof value === 'string' || typeof value === 'number' } /** * Create a cached version of a pure function. */ function cached (fn) { var cache = Object.create(null) return function cachedFn (str) { var hit = cache[str] return hit || (cache[str] = fn(str)) } } /** * Camelize a hyphen-delmited string. */ var camelizeRE = /-(\w)/g var camelize = cached(function (str) { return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }) }) /** * Capitalize a string. */ var capitalize = cached(function (str) { return str.charAt(0).toUpperCase() + str.slice(1) }) /** * Hyphenate a camelCase string. */ var hyphenateRE = /([^-])([A-Z])/g var hyphenate = cached(function (str) { return str .replace(hyphenateRE, '$1-$2') .replace(hyphenateRE, '$1-$2') .toLowerCase() }) /** * Simple bind, faster than native */ function bind (fn, ctx) { function boundFn (a) { var l = arguments.length return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx) } // record original fn length boundFn._length = fn.length return boundFn } /** * Convert an Array-like object to a real Array. */ function toArray (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. */ function extend (to, _from) { for (var key in _from) { to[key] = _from[key] } return to } /** * Quick object check - this is primarily used to tell * Objects from primitive values when we know the value * is a JSON-compliant type. */ function isObject (obj) { return obj !== null && typeof obj === 'object' } /** * Strict object type check. Only returns true * for plain JavaScript objects. */ var toString = Object.prototype.toString var OBJECT_STRING = '[object Object]' function isPlainObject (obj) { return toString.call(obj) === OBJECT_STRING } /** * Merge an Array of Objects into a single Object. */ function toObject (arr) { var res = {} for (var i = 0; i < arr.length; i++) { if (arr[i]) { extend(res, arr[i]) } } return res } /** * Perform no operation. */ function noop () {} /** * Always return false. */ var no = function () { return false; } /** * Generate a static keys string from compiler modules. */ function genStaticKeys (modules) { return modules.reduce(function (keys, m) { return keys.concat(m.staticKeys || []) }, []).join(',') } /** * Check if two values are loosely equal - that is, * if they are plain objects, do they have the same shape? */ function looseEqual (a, b) { /* eslint-disable eqeqeq */ return a == b || ( isObject(a) && isObject(b) ? JSON.stringify(a) === JSON.stringify(b) : false ) /* eslint-enable eqeqeq */ } function looseIndexOf (arr, val) { for (var i = 0; i < arr.length; i++) { if (looseEqual(arr[i], val)) { return i } } return -1 } /* */ var config = { /** * Option merge strategies (used in core/util/options) */ optionMergeStrategies: Object.create(null), /** * Whether to suppress warnings. */ silent: false, /** * Whether to enable devtools */ devtools: "development" !== 'production', /** * Error handler for watcher errors */ errorHandler: null, /** * Ignore certain custom elements */ ignoredElements: null, /** * Custom user key aliases for v-on */ keyCodes: Object.create(null), /** * Check if a tag is reserved so that it cannot be registered as a * component. This is platform-dependent and may be overwritten. */ isReservedTag: no, /** * Check if a tag is an unknown element. * Platform-dependent. */ isUnknownElement: no, /** * Get the namespace of an element */ getTagNamespace: noop, /** * Check if an attribute must be bound using property, e.g. value * Platform-dependent. */ mustUseProp: no, /** * List of asset types that a component can own. */ _assetTypes: [ 'component', 'directive', 'filter' ], /** * List of lifecycle hooks. */ _lifecycleHooks: [ 'beforeCreate', 'created', 'beforeMount', 'mounted', 'beforeUpdate', 'updated', 'beforeDestroy', 'destroyed', 'activated', 'deactivated' ], /** * Max circular updates allowed in a scheduler flush cycle. */ _maxUpdateCount: 100, /** * Server rendering? */ _isServer: "client" === 'server' } /* */ /** * Check if a string starts with $ or _ */ function isReserved (str) { var c = (str + '').charCodeAt(0) return c === 0x24 || c === 0x5F } /** * Define a property. */ function def (obj, key, val, enumerable) { Object.defineProperty(obj, key, { value: val, enumerable: !!enumerable, writable: true, configurable: true }) } /** * Parse simple path. */ var bailRE = /[^\w\.\$]/ function parsePath (path) { if (bailRE.test(path)) { return } else { var segments = path.split('.') return function (obj) { for (var i = 0; i < segments.length; i++) { if (!obj) { return } obj = obj[segments[i]] } return obj } } } /* */ // can we use __proto__? var hasProto = '__proto__' in {} // Browser environment sniffing var inBrowser = typeof window !== 'undefined' && Object.prototype.toString.call(window) !== '[object Object]' var UA = inBrowser && window.navigator.userAgent.toLowerCase() var isIE = UA && /msie|trident/.test(UA) var isIE9 = UA && UA.indexOf('msie 9.0') > 0 var isEdge = UA && UA.indexOf('edge/') > 0 var isAndroid = UA && UA.indexOf('android') > 0 // detect devtools var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__ /** * Defer a task to execute it asynchronously. Ideally this * should be executed as a microtask, but MutationObserver is unreliable * in iOS UIWebView so we use a setImmediate shim and fallback to setTimeout. */ var nextTick = (function () { var callbacks = [] var pending = false var timerFunc function nextTickHandler () { pending = false var copies = callbacks.slice(0) callbacks = [] for (var i = 0; i < copies.length; i++) { copies[i]() } } /* istanbul ignore else */ if (inBrowser && window.postMessage && !window.importScripts && // not in WebWorker !(isAndroid && !window.requestAnimationFrame) // not in Android <= 4.3 ) { var NEXT_TICK_TOKEN = '__vue__nextTick__' window.addEventListener('message', function (e) { if (e.source === window && e.data === NEXT_TICK_TOKEN) { nextTickHandler() } }) timerFunc = function () { window.postMessage(NEXT_TICK_TOKEN, '*') } } else { timerFunc = (typeof global !== 'undefined' && global.setImmediate) || setTimeout } return function queueNextTick (cb, ctx) { var func = ctx ? function () { cb.call(ctx) } : cb callbacks.push(func) if (pending) { return } pending = true timerFunc(nextTickHandler, 0) } })() var _Set /* istanbul ignore if */ if (typeof Set !== 'undefined' && /native code/.test(Set.toString())) { // use native Set when available. _Set = Set } else { // a non-standard Set polyfill that only works with primitive keys. _Set = (function () { function Set () { this.set = Object.create(null) } Set.prototype.has = function has (key) { return this.set[key] !== undefined }; Set.prototype.add = function add (key) { this.set[key] = 1 }; Set.prototype.clear = function clear () { this.set = Object.create(null) }; return Set; }()) } /* not type checking this file because flow doesn't play well with Proxy */ var hasProxy; var proxyHandlers; var initProxy; if ("development" !== 'production') { var allowedGlobals = makeMap( 'Infinity,undefined,NaN,isFinite,isNaN,' + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + 'require' // for Webpack/Browserify ) hasProxy = typeof Proxy !== 'undefined' && Proxy.toString().match(/native code/) proxyHandlers = { has: function has (target, key) { var has = key in target var isAllowed = allowedGlobals(key) || key.charAt(0) === '_' if (!has && !isAllowed) { warn( "Property or method \"" + key + "\" is not defined on the instance but " + "referenced during render. Make sure to declare reactive data " + "properties in the data option.", target ) } return has || !isAllowed } } initProxy = function initProxy (vm) { if (hasProxy) { vm._renderProxy = new Proxy(vm, proxyHandlers) } else { vm._renderProxy = vm } } } /* */ var uid$2 = 0 /** * A dep is an observable that can have multiple * directives subscribing to it. */ var Dep = function Dep () { this.id = uid$2++ this.subs = [] }; Dep.prototype.addSub = function addSub (sub) { this.subs.push(sub) }; Dep.prototype.removeSub = function removeSub (sub) { remove(this.subs, sub) }; Dep.prototype.depend = function depend () { if (Dep.target) { Dep.target.addDep(this) } }; Dep.prototype.notify = function notify () { // stablize the subscriber list first var subs = this.subs.slice() for (var i = 0, l = subs.length; i < l; i++) { subs[i].update() } }; // the current target watcher being evaluated. // this is globally unique because there could be only one // watcher being evaluated at any time. Dep.target = null var targetStack = [] function pushTarget (_target) { if (Dep.target) { targetStack.push(Dep.target) } Dep.target = _target } function popTarget () { Dep.target = targetStack.pop() } /* */ var queue = [] var has = {} var circular = {} var waiting = false var flushing = false var index = 0 /** * Reset the scheduler's state. */ function resetSchedulerState () { queue.length = 0 has = {} if ("development" !== 'production') { circular = {} } waiting = flushing = false } /** * Flush both queues and run the watchers. */ function flushSchedulerQueue () { flushing = true // Sort queue before flush. // This ensures that: // 1. Components are updated from parent to child. (because parent is always // created before the child) // 2. A component's user watchers are run before its render watcher (because // user watchers are created before the render watcher) // 3. If a component is destroyed during a parent component's watcher run, // its watchers can be skipped. queue.sort(function (a, b) { return a.id - b.id; }) // do not cache length because more watchers might be pushed // as we run existing watchers for (index = 0; index < queue.length; index++) { var watcher = queue[index] var id = watcher.id has[id] = null watcher.run() // in dev build, check and stop circular updates. if ("development" !== 'production' && has[id] != null) { circular[id] = (circular[id] || 0) + 1 if (circular[id] > config._maxUpdateCount) { warn( 'You may have an infinite update loop ' + ( watcher.user ? ("in watcher with expression \"" + (watcher.expression) + "\"") : "in a component render function." ), watcher.vm ) break } } } // devtool hook /* istanbul ignore if */ if (devtools && config.devtools) { devtools.emit('flush') } resetSchedulerState() } /** * Push a watcher into the watcher queue. * Jobs with duplicate IDs will be skipped unless it's * pushed when the queue is being flushed. */ function queueWatcher (watcher) { var id = watcher.id if (has[id] == null) { has[id] = true if (!flushing) { queue.push(watcher) } else { // if already flushing, splice the watcher based on its id // if already past its id, it will be run next immediately. var i = queue.length - 1 while (i >= 0 && queue[i].id > watcher.id) { i-- } queue.splice(Math.max(i, index) + 1, 0, watcher) } // queue the flush if (!waiting) { waiting = true nextTick(flushSchedulerQueue) } } } /* */ var uid$1 = 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. */ var Watcher = function Watcher ( vm, expOrFn, cb, options ) { if ( options === void 0 ) options = {}; this.vm = vm vm._watchers.push(this) // options this.deep = !!options.deep this.user = !!options.user this.lazy = !!options.lazy this.sync = !!options.sync this.expression = expOrFn.toString() this.cb = cb this.id = ++uid$1 // uid for batching this.active = true this.dirty = this.lazy // for lazy watchers this.deps = [] this.newDeps = [] this.depIds = new _Set() this.newDepIds = new _Set() // parse expression for getter if (typeof expOrFn === 'function') { this.getter = expOrFn } else { this.getter = parsePath(expOrFn) if (!this.getter) { this.getter = function () {} "development" !== 'production' && warn( "Failed watching path: \"" + expOrFn + "\" " + 'Watcher only accepts simple dot-delimited paths. ' + 'For full control, use a function instead.', vm ) } } this.value = this.lazy ? undefined : this.get() }; /** * Evaluate the getter, and re-collect dependencies. */ Watcher.prototype.get = function get () { pushTarget(this) var value = this.getter.call(this.vm, this.vm) // "touch" every property so they are all tracked as // dependencies for deep watching if (this.deep) { traverse(value) } popTarget() this.cleanupDeps() return value }; /** * Add a dependency to this directive. */ Watcher.prototype.addDep = function addDep (dep) { var id = dep.id if (!this.newDepIds.has(id)) { this.newDepIds.add(id) this.newDeps.push(dep) if (!this.depIds.has(id)) { dep.addSub(this) } } }; /** * Clean up for dependency collection. */ Watcher.prototype.cleanupDeps = function cleanupDeps () { var this$1 = this; var i = this.deps.length while (i--) { var dep = this$1.deps[i] if (!this$1.newDepIds.has(dep.id)) { dep.removeSub(this$1) } } var tmp = this.depIds this.depIds = this.newDepIds this.newDepIds = tmp this.newDepIds.clear() tmp = this.deps this.deps = this.newDeps this.newDeps = tmp this.newDeps.length = 0 }; /** * Subscriber interface. * Will be called when a dependency changes. */ Watcher.prototype.update = function update () { /* istanbul ignore else */ if (this.lazy) { this.dirty = true } else if (this.sync) { this.run() } else { queueWatcher(this) } }; /** * Scheduler job interface. * Will be called by the scheduler. */ Watcher.prototype.run = function run () { if (this.active) { var value = this.get() if ( value !== this.value || // Deep watchers and watchers on Object/Arrays should fire even // when the value is the same, because the value may // have mutated. isObject(value) || this.deep ) { // set new value var oldValue = this.value this.value = value if (this.user) { try { this.cb.call(this.vm, value, oldValue) } catch (e) { "development" !== 'production' && warn( ("Error in watcher \"" + (this.expression) + "\""), this.vm ) /* istanbul ignore else */ if (config.errorHandler) { config.errorHandler.call(null, e, this.vm) } else { throw e } } } else { this.cb.call(this.vm, value, oldValue) } } } }; /** * Evaluate the value of the watcher. * This only gets called for lazy watchers. */ Watcher.prototype.evaluate = function evaluate () { this.value = this.get() this.dirty = false }; /** * Depend on all deps collected by this watcher. */ Watcher.prototype.depend = function depend () { var this$1 = this; var i = this.deps.length while (i--) { this$1.deps[i].depend() } }; /** * Remove self from all dependencies' subcriber list. */ Watcher.prototype.teardown = function teardown () { var this$1 = this; if (this.active) { // remove self from vm's watcher list // this is a somewhat expensive operation so we skip it // if the vm is being destroyed or is performing a v-for // re-render (the watcher list is then filtered by v-for). if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) { remove(this.vm._watchers, this) } var i = this.deps.length while (i--) { this$1.deps[i].removeSub(this$1) } this.active = false } }; /** * Recursively traverse an object to evoke all converted * getters, so that every nested property inside the object * is collected as a "deep" dependency. */ var seenObjects = new _Set() function traverse (val, seen) { var i, keys if (!seen) { seen = seenObjects seen.clear() } var isA = Array.isArray(val) var isO = isObject(val) if ((isA || isO) && Object.isExtensible(val)) { if (val.__ob__) { var depId = val.__ob__.dep.id if (seen.has(depId)) { return } else { seen.add(depId) } } if (isA) { i = val.length while (i--) { traverse(val[i], seen) } } else if (isO) { keys = Object.keys(val) i = keys.length while (i--) { traverse(val[keys[i]], seen) } } } } /* * not type checking this file because flow doesn't play well with * dynamically accessing methods on Array prototype */ 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] def(arrayMethods, method, function mutator () { var arguments$1 = arguments; // avoid leaking arguments: // http://jsperf.com/closure-with-arguments var i = arguments.length var args = new Array(i) while (i--) { args[i] = arguments$1[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.dep.notify() return result }) }) /* */ var arrayKeys = Object.getOwnPropertyNames(arrayMethods) /** * By default, when a reactive property is set, the new value is * also converted to become reactive. However when passing down props, * we don't want to force conversion because the value may be a nested value * under a frozen data structure. Converting it would defeat the optimization. */ var observerState = { shouldConvert: true, isSettingProps: false } /** * 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. */ var Observer = function Observer (value) { this.value = value this.dep = new Dep() this.vmCount = 0 def(value, '__ob__', this) if (Array.isArray(value)) { var augment = hasProto ? protoAugment : copyAugment augment(value, arrayMethods, arrayKeys) this.observeArray(value) } else { this.walk(value) } }; /** * Walk through each property and convert them into * getter/setters. This method should only be called when * value type is Object. */ Observer.prototype.walk = function walk (obj) { var keys = Object.keys(obj) for (var i = 0; i < keys.length; i++) { defineReactive(obj, keys[i], obj[keys[i]]) } }; /** * Observe a list of Array items. */ Observer.prototype.observeArray = function observeArray (items) { for (var i = 0, l = items.length; i < l; i++) { observe(items[i]) } }; // helpers /** * Augment an target Object or Array by intercepting * the prototype chain using __proto__ */ function protoAugment (target, src) { /* eslint-disable no-proto */ target.__proto__ = src /* eslint-enable no-proto */ } /** * Augment an target Object or Array by defining * hidden properties. * * istanbul ignore next */ function copyAugment (target, src, keys) { for (var i = 0, l = keys.length; i < l; i++) { var key = keys[i] def(target, key, src[key]) } } /** * 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. */ function observe (value) { if (!isObject(value)) { return } var ob if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { ob = value.__ob__ } else if ( observerState.shouldConvert && !config._isServer && (Array.isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue ) { ob = new Observer(value) } return ob } /** * Define a reactive property on an Object. */ function defineReactive ( obj, key, val, customSetter ) { var dep = new Dep() var property = Object.getOwnPropertyDescriptor(obj, key) if (property && property.configurable === false) { return } // cater for pre-defined getter/setters var getter = property && property.get var setter = property && property.set var childOb = observe(val) Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () { var value = getter ? getter.call(obj) : val if (Dep.target) { dep.depend() if (childOb) { childOb.dep.depend() } if (Array.isArray(value)) { for (var e = void 0, i = 0, l = value.length; i < l; i++) { e = value[i] e && e.__ob__ && e.__ob__.dep.depend() } } } return value }, set: function reactiveSetter (newVal) { var value = getter ? getter.call(obj) : val if (newVal === value) { return } if ("development" !== 'production' && customSetter) { customSetter() } if (setter) { setter.call(obj, newVal) } else { val = newVal } childOb = observe(newVal) dep.notify() } }) } /** * Set a property on an object. Adds the new property and * triggers change notification if the property doesn't * already exist. */ function set (obj, key, val) { if (Array.isArray(obj)) { obj.splice(key, 1, val) return val } if (hasOwn(obj, key)) { obj[key] = val return } var ob = obj.__ob__ if (obj._isVue || (ob && ob.vmCount)) { "development" !== 'production' && warn( 'Avoid adding reactive properties to a Vue instance or its root $data ' + 'at runtime - declare it upfront in the data option.' ) return } if (!ob) { obj[key] = val return } defineReactive(ob.value, key, val) ob.dep.notify() return val } /** * Delete a property and trigger change if necessary. */ function del (obj, key) { var ob = obj.__ob__ if (obj._isVue || (ob && ob.vmCount)) { "development" !== 'production' && warn( 'Avoid deleting properties on a Vue instance or its root $data ' + '- just set it to null.' ) return } if (!hasOwn(obj, key)) { return } delete obj[key] if (!ob) { return } ob.dep.notify() } /* */ function initState (vm) { vm._watchers = [] initProps(vm) initData(vm) initComputed(vm) initMethods(vm) initWatch(vm) } function initProps (vm) { var props = vm.$options.props if (props) { var propsData = vm.$options.propsData || {} var keys = vm.$options._propKeys = Object.keys(props) var isRoot = !vm.$parent // root instance props should be converted observerState.shouldConvert = isRoot var loop = function ( i ) { var key = keys[i] /* istanbul ignore else */ if ("development" !== 'production') { defineReactive(vm, key, validateProp(key, props, propsData, vm), function () { if (vm.$parent && !observerState.isSettingProps) { warn( "Avoid mutating a prop directly since the value will be " + "overwritten whenever the parent component re-renders. " + "Instead, use a data or computed property based on the prop's " + "value. Prop being mutated: \"" + key + "\"", vm ) } }) } else {} }; for (var i = 0; i < keys.length; i++) loop( i ); observerState.shouldConvert = true } } function initData (vm) { var data = vm.$options.data data = vm._data = typeof data === 'function' ? data.call(vm) : data || {} if (!isPlainObject(data)) { data = {} "development" !== 'production' && warn( 'data functions should return an object.', vm ) } // proxy data on instance var keys = Object.keys(data) var props = vm.$options.props var i = keys.length while (i--) { if (props && hasOwn(props, keys[i])) { "development" !== 'production' && warn( "The data property \"" + (keys[i]) + "\" is already declared as a prop. " + "Use prop default value instead.", vm ) } else { proxy(vm, keys[i]) } } // observe data observe(data) data.__ob__ && data.__ob__.vmCount++ } var computedSharedDefinition = { enumerable: true, configurable: true, get: noop, set: noop } function initComputed (vm) { var computed = vm.$options.computed if (computed) { for (var key in computed) { var userDef = computed[key] if (typeof userDef === 'function') { computedSharedDefinition.get = makeComputedGetter(userDef, vm) computedSharedDefinition.set = noop } else { computedSharedDefinition.get = userDef.get ? userDef.cache !== false ? makeComputedGetter(userDef.get, vm) : bind(userDef.get, vm) : noop computedSharedDefinition.set = userDef.set ? bind(userDef.set, vm) : noop } Object.defineProperty(vm, key, computedSharedDefinition) } } } function makeComputedGetter (getter, owner) { var watcher = new Watcher(owner, getter, noop, { lazy: true }) return function computedGetter () { if (watcher.dirty) { watcher.evaluate() } if (Dep.target) { watcher.depend() } return watcher.value } } function initMethods (vm) { var methods = vm.$options.methods if (methods) { for (var key in methods) { if (methods[key] != null) { vm[key] = bind(methods[key], vm) } else if ("development" !== 'production') { warn(("Method \"" + key + "\" is undefined in options."), vm) } } } } function initWatch (vm) { var watch = vm.$options.watch if (watch) { for (var key in watch) { var handler = watch[key] if (Array.isArray(handler)) { for (var i = 0; i < handler.length; i++) { createWatcher(vm, key, handler[i]) } } else { createWatcher(vm, key, handler) } } } } function createWatcher (vm, key, handler) { var options if (isPlainObject(handler)) { options = handler handler = handler.handler } if (typeof handler === 'string') { handler = vm[handler] } vm.$watch(key, handler, options) } function stateMixin (Vue) { // flow somehow has problems with directly declared definition object // when using Object.defineProperty, so we have to procedurally build up // the object here. var dataDef = {} dataDef.get = function () { return this._data } if ("development" !== 'production') { dataDef.set = function (newData) { warn( 'Avoid replacing instance root $data. ' + 'Use nested data properties instead.', this ) } } Object.defineProperty(Vue.prototype, '$data', dataDef) Vue.prototype.$set = set Vue.prototype.$delete = del Vue.prototype.$watch = function ( expOrFn, cb, options ) { var vm = this options = options || {} options.user = true var watcher = new Watcher(vm, expOrFn, cb, options) if (options.immediate) { cb.call(vm, watcher.value) } return function unwatchFn () { watcher.teardown() } } } function proxy (vm, key) { if (!isReserved(key)) { Object.defineProperty(vm, key, { configurable: true, enumerable: true, get: function proxyGetter () { return vm._data[key] }, set: function proxySetter (val) { vm._data[key] = val } }) } } /* */ var VNode = function VNode ( tag, data, children, text, elm, ns, context, componentOptions ) { this.tag = tag this.data = data this.children = children this.text = text this.elm = elm this.ns = ns this.context = context this.key = data && data.key this.componentOptions = componentOptions this.child = undefined this.parent = undefined this.raw = false this.isStatic = false this.isRootInsert = true this.isComment = false this.isCloned = false }; var emptyVNode = function () { var node = new VNode() node.text = '' node.isComment = true return node } // optimized shallow clone // used for static nodes and slot nodes because they may be reused across // multiple renders, cloning them avoids errors when DOM manipulations rely // on their elm reference. function cloneVNode (vnode) { var cloned = new VNode( vnode.tag, vnode.data, vnode.children, vnode.text, vnode.elm, vnode.ns, vnode.context, vnode.componentOptions ) cloned.isStatic = vnode.isStatic cloned.key = vnode.key cloned.isCloned = true return cloned } function cloneVNodes (vnodes) { var res = new Array(vnodes.length) for (var i = 0; i < vnodes.length; i++) { res[i] = cloneVNode(vnodes[i]) } return res } /* */ function normalizeChildren ( children, ns, nestedIndex ) { if (isPrimitive(children)) { return [createTextVNode(children)] } if (Array.isArray(children)) { var res = [] for (var i = 0, l = children.length; i < l; i++) { var c = children[i] var last = res[res.length - 1] // nested if (Array.isArray(c)) { res.push.apply(res, normalizeChildren(c, ns, i)) } else if (isPrimitive(c)) { if (last && last.text) { last.text += String(c) } else if (c !== '') { // convert primitive to vnode res.push(createTextVNode(c)) } } else if (c instanceof VNode) { if (c.text && last && last.text) { last.text += c.text } else { // inherit parent namespace if (ns) { applyNS(c, ns) } // default key for nested array children (likely generated by v-for) if (c.key == null && nestedIndex != null) { c.key = "__vlist_" + nestedIndex + "_" + i + "__" } res.push(c) } } } return res } } function createTextVNode (val) { return new VNode(undefined, undefined, undefined, String(val)) } function applyNS (vnode, ns) { if (vnode.tag && !vnode.ns) { vnode.ns = ns if (vnode.children) { for (var i = 0, l = vnode.children.length; i < l; i++) { applyNS(vnode.children[i], ns) } } } } function getFirstComponentChild (children) { return children && children.filter(function (c) { return c && c.componentOptions; })[0] } function mergeVNodeHook (def, key, hook) { var oldHook = def[key] if (oldHook) { var injectedHash = def.__injected || (def.__injected = {}) if (!injectedHash[key]) { injectedHash[key] = true def[key] = function () { oldHook.apply(this, arguments) hook.apply(this, arguments) } } } else { def[key] = hook } } function updateListeners ( on, oldOn, add, remove ) { var name, cur, old, fn, event, capture for (name in on) { cur = on[name] old = oldOn[name] if (!cur) { "development" !== 'production' && warn( ("Handler for event \"" + name + "\" is undefined.") ) } else if (!old) { capture = name.charAt(0) === '!' event = capture ? name.slice(1) : name if (Array.isArray(cur)) { add(event, (cur.invoker = arrInvoker(cur)), capture) } else { if (!cur.invoker) { fn = cur cur = on[name] = {} cur.fn = fn cur.invoker = fnInvoker(cur) } add(event, cur.invoker, capture) } } else if (cur !== old) { if (Array.isArray(old)) { old.length = cur.length for (var i = 0; i < old.length; i++) { old[i] = cur[i] } on[name] = old } else { old.fn = cur on[name] = old } } } for (name in oldOn) { if (!on[name]) { event = name.charAt(0) === '!' ? name.slice(1) : name remove(event, oldOn[name].invoker) } } } function arrInvoker (arr) { return function (ev) { var arguments$1 = arguments; var single = arguments.length === 1 for (var i = 0; i < arr.length; i++) { single ? arr[i](ev) : arr[i].apply(null, arguments$1) } } } function fnInvoker (o) { return function (ev) { var single = arguments.length === 1 single ? o.fn(ev) : o.fn.apply(null, arguments) } } /* */ var activeInstance = null function initLifecycle (vm) { var options = vm.$options // locate first non-abstract parent var parent = options.parent if (parent && !options.abstract) { while (parent.$options.abstract && parent.$parent) { parent = parent.$parent } parent.$children.push(vm) } vm.$parent = parent vm.$root = parent ? parent.$root : vm vm.$children = [] vm.$refs = {} vm._watcher = null vm._inactive = false vm._isMounted = false vm._isDestroyed = false vm._isBeingDestroyed = false } function lifecycleMixin (Vue) { Vue.prototype._mount = function ( el, hydrating ) { var vm = this vm.$el = el if (!vm.$options.render) { vm.$options.render = emptyVNode if ("development" !== 'production') { /* istanbul ignore if */ if (vm.$options.template) { warn( 'You are using the runtime-only build of Vue where the template ' + 'option is not available. Either pre-compile the templates into ' + 'render functions, or use the compiler-included build.', vm ) } else { warn( 'Failed to mount component: template or render function not defined.', vm ) } } } callHook(vm, 'beforeMount') vm._watcher = new Watcher(vm, function () { vm._update(vm._render(), hydrating) }, noop) hydrating = false // root instance, call mounted on self // mounted is called for child components in its inserted hook if (vm.$root === vm) { vm._isMounted = true callHook(vm, 'mounted') } return vm } Vue.prototype._update = function (vnode, hydrating) { var vm = this if (vm._isMounted) { callHook(vm, 'beforeUpdate') } var prevEl = vm.$el var prevActiveInstance = activeInstance activeInstance = vm var prevVnode = vm._vnode vm._vnode = vnode if (!prevVnode) { // Vue.prototype.__patch__ is injected in entry points // based on the rendering backend used. vm.$el = vm.__patch__(vm.$el, vnode, hydrating) } else { vm.$el = vm.__patch__(prevVnode, vnode) } activeInstance = prevActiveInstance // update __vue__ reference if (prevEl) { prevEl.__vue__ = null } if (vm.$el) { vm.$el.__vue__ = vm } // if parent is an HOC, update its $el as well if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) { vm.$parent.$el = vm.$el } if (vm._isMounted) { callHook(vm, 'updated') } } Vue.prototype._updateFromParent = function ( propsData, listeners, parentVnode, renderChildren ) { var vm = this var hasChildren = !!(vm.$options._renderChildren || renderChildren) vm.$options._parentVnode = parentVnode vm.$options._renderChildren = renderChildren // update props if (propsData && vm.$options.props) { observerState.shouldConvert = false if ("development" !== 'production') { observerState.isSettingProps = true } var propKeys = vm.$options._propKeys || [] for (var i = 0; i < propKeys.length; i++) { var key = propKeys[i] vm[key] = validateProp(key, vm.$options.props, propsData, vm) } observerState.shouldConvert = true if ("development" !== 'production') { observerState.isSettingProps = false } } // update listeners if (listeners) { var oldListeners = vm.$options._parentListeners vm.$options._parentListeners = listeners vm._updateListeners(listeners, oldListeners) } // resolve slots + force update if has children if (hasChildren) { vm.$slots = resolveSlots(renderChildren) vm.$forceUpdate() } } Vue.prototype.$forceUpdate = function () { var vm = this if (vm._watcher) { vm._watcher.update() } } Vue.prototype.$destroy = function () { var vm = this if (vm._isBeingDestroyed) { return } callHook(vm, 'beforeDestroy') vm._isBeingDestroyed = true // remove self from parent var parent = vm.$parent if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) { remove(parent.$children, vm) } // teardown watchers if (vm._watcher) { vm._watcher.teardown() } var i = vm._watchers.length while (i--) { vm._watchers[i].teardown() } // remove reference from data ob // frozen object may not have observer. if (vm._data.__ob__) { vm._data.__ob__.vmCount-- } // call the last hook... vm._isDestroyed = true callHook(vm, 'destroyed') // turn off all instance listeners. vm.$off() // remove __vue__ reference if (vm.$el) { vm.$el.__vue__ = null } } } function callHook (vm, hook) { var handlers = vm.$options[hook] if (handlers) { for (var i = 0, j = handlers.length; i < j; i++) { handlers[i].call(vm) } } vm.$emit('hook:' + hook) } /* */ var hooks = { init: init, prepatch: prepatch, insert: insert, destroy: destroy } var hooksToMerge = Object.keys(hooks) function createComponent ( Ctor, data, context, children, tag ) { if (!Ctor) { return } if (isObject(Ctor)) { Ctor = Vue.extend(Ctor) } if (typeof Ctor !== 'function') { if ("development" !== 'production') { warn(("Invalid Component definition: " + (String(Ctor))), context) } return } // async component if (!Ctor.cid) { if (Ctor.resolved) { Ctor = Ctor.resolved } else { Ctor = resolveAsyncComponent(Ctor, function () { // it's ok to queue this on every render because // $forceUpdate is buffered by the scheduler. context.$forceUpdate() }) if (!Ctor) { // return nothing if this is indeed an async component // wait for the callback to trigger parent update. return } } } data = data || {} // extract props var propsData = extractProps(data, Ctor) // functional component if (Ctor.options.functional) { return createFunctionalComponent(Ctor, propsData, data, context, children) } // extract listeners, since these needs to be treated as // child component listeners instead of DOM listeners var listeners = data.on // replace with listeners with .native modifier data.on = data.nativeOn if (Ctor.options.abstract) { // abstract components do not keep anything // other than props & listeners data = {} } // merge component management hooks onto the placeholder node mergeHooks(data) // return a placeholder vnode var name = Ctor.options.name || tag var vnode = new VNode( ("vue-component-" + (Ctor.cid) + (name ? ("-" + name) : '')), data, undefined, undefined, undefined, undefined, context, { Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children } ) return vnode } function createFunctionalComponent ( Ctor, propsData, data, context, children ) { var props = {} var propOptions = Ctor.options.props if (propOptions) { for (var key in propOptions) { props[key] = validateProp(key, propOptions, propsData) } } return Ctor.options.render.call( null, context.$createElement, { props: props, data: data, parent: context, children: normalizeChildren(children), slots: function () { return resolveSlots(children); } } ) } function createComponentInstanceForVnode ( vnode, // we know it's MountedComponentVNode but flow doesn't parent // activeInstance in lifecycle state ) { var vnodeComponentOptions = vnode.componentOptions var options = { _isComponent: true, parent: parent, propsData: vnodeComponentOptions.propsData, _componentTag: vnodeComponentOptions.tag, _parentVnode: vnode, _parentListeners: vnodeComponentOptions.listeners, _renderChildren: vnodeComponentOptions.children } // check inline-template render functions var inlineTemplate = vnode.data.inlineTemplate if (inlineTemplate) { options.render = inlineTemplate.render options.staticRenderFns = inlineTemplate.staticRenderFns } return new vnodeComponentOptions.Ctor(options) } function init (vnode, hydrating) { if (!vnode.child || vnode.child._isDestroyed) { var child = vnode.child = createComponentInstanceForVnode(vnode, activeInstance) child.$mount(hydrating ? vnode.elm : undefined, hydrating) } } function prepatch ( oldVnode, vnode ) { var options = vnode.componentOptions var child = vnode.child = oldVnode.child child._updateFromParent( options.propsData, // updated props options.listeners, // updated listeners vnode, // new parent vnode options.children // new children ) } function insert (vnode) { if (!vnode.child._isMounted) { vnode.child._isMounted = true callHook(vnode.child, 'mounted') } if (vnode.data.keepAlive) { vnode.child._inactive = false callHook(vnode.child, 'activated') } } function destroy (vnode) { if (!vnode.child._isDestroyed) { if (!vnode.data.keepAlive) { vnode.child.$destroy() } else { vnode.child._inactive = true callHook(vnode.child, 'deactivated') } } } function resolveAsyncComponent ( factory, cb ) { if (factory.requested) { // pool callbacks factory.pendingCallbacks.push(cb) } else { factory.requested = true var cbs = factory.pendingCallbacks = [cb] var sync = true var resolve = function (res) { if (isObject(res)) { res = Vue.extend(res) } // cache resolved factory.resolved = res // invoke callbacks only if this is not a synchronous resolve // (async resolves are shimmed as synchronous during SSR) if (!sync) { for (var i = 0, l = cbs.length; i < l; i++) { cbs[i](res) } } } var reject = function (reason) { "development" !== 'production' && warn( "Failed to resolve async component: " + (String(factory)) + (reason ? ("\nReason: " + reason) : '') ) } var res = factory(resolve, reject) // handle promise if (res && typeof res.then === 'function' && !factory.resolved) { res.then(resolve, reject) } sync = false // return in case resolved synchronously return factory.resolved } } function extractProps (data, Ctor) { // we are only extrating raw values here. // validation and default values are handled in the child // component itself. var propOptions = Ctor.options.props if (!propOptions) { return } var res = {} var attrs = data.attrs; var props = data.props; var domProps = data.domProps; if (attrs || props || domProps) { for (var key in propOptions) { var altKey = hyphenate(key) checkProp(res, props, key, altKey, true) || checkProp(res, attrs, key, altKey) || checkProp(res, domProps, key, altKey) } } return res } function checkProp ( res, hash, key, altKey, preserve ) { if (hash) { if (hasOwn(hash, key)) { res[key] = hash[key] if (!preserve) { delete hash[key] } return true } else if (hasOwn(hash, altKey)) { res[key] = hash[altKey] if (!preserve) { delete hash[altKey] } return true } } return false } function mergeHooks (data) { if (!data.hook) { data.hook = {} } for (var i = 0; i < hooksToMerge.length; i++) { var key = hooksToMerge[i] var fromParent = data.hook[key] var ours = hooks[key] data.hook[key] = fromParent ? mergeHook$1(ours, fromParent) : ours } } function mergeHook$1 (a, b) { // since all hooks have at most two args, use fixed args // to avoid having to use fn.apply(). return function (_, __) { a(_, __) b(_, __) } } /* */ // wrapper function for providing a more flexible interface // without getting yelled at by flow function createElement ( tag, data, children ) { if (data && (Array.isArray(data) || typeof data !== 'object')) { children = data data = undefined } // make sure to use real instance instead of proxy as context return _createElement(this._self, tag, data, children) } function _createElement ( context, tag, data, children ) { if (data && data.__ob__) { "development" !== 'production' && warn( "Avoid using observed data object as vnode data: " + (JSON.stringify(data)) + "\n" + 'Always create fresh vnode data objects in each render!', context ) return } if (!tag) { // in case of component :is set to falsy value return emptyVNode() } if (typeof tag === 'string') { var Ctor var ns = config.getTagNamespace(tag) if (config.isReservedTag(tag)) { // platform built-in elements return new VNode( tag, data, normalizeChildren(children, ns), undefined, undefined, ns, context ) } else if ((Ctor = resolveAsset(context.$options, 'components', tag))) { // component return createComponent(Ctor, data, context, children, tag) } else { // unknown or unlisted namespaced elements // check at runtime because it may get assigned a namespace when its // parent normalizes children return new VNode( tag, data, normalizeChildren(children, ns), undefined, undefined, ns, context ) } } else { // direct component options / constructor return createComponent(tag, data, context, children) } } /* */ function initRender (vm) { vm.$vnode = null // the placeholder node in parent tree vm._vnode = null // the root of the child tree vm._staticTrees = null vm.$slots = resolveSlots(vm.$options._renderChildren) // bind the public createElement fn to this instance // so that we get proper render context inside it. vm.$createElement = bind(createElement, vm) if (vm.$options.el) { vm.$mount(vm.$options.el) } } function renderMixin (Vue) { Vue.prototype.$nextTick = function (fn) { nextTick(fn, this) } Vue.prototype._render = function () { var vm = this var ref = vm.$options; var render = ref.render; var staticRenderFns = ref.staticRenderFns; var _parentVnode = ref._parentVnode; if (vm._isMounted) { // clone slot nodes on re-renders for (var key in vm.$slots) { vm.$slots[key] = cloneVNodes(vm.$slots[key]) } } if (staticRenderFns && !vm._staticTrees) { vm._staticTrees = [] } // set parent vnode. this allows render functions to have access // to the data on the placeholder node. vm.$vnode = _parentVnode // render self var vnode try { vnode = render.call(vm._renderProxy, vm.$createElement) } catch (e) { if ("development" !== 'production') { warn(("Error when rendering " + (formatComponentName(vm)) + ":")) } /* istanbul ignore else */ if (config.errorHandler) { config.errorHandler.call(null, e, vm) } else { if (config._isServer) { throw e } else { setTimeout(function () { throw e }, 0) } } // return previous vnode to prevent render error causing blank component vnode = vm._vnode } // return empty vnode in case the render function errored out if (!(vnode instanceof VNode)) { if ("development" !== 'production' && Array.isArray(vnode)) { warn( 'Multiple root nodes returned from render function. Render function ' + 'should return a single root node.', vm ) } vnode = emptyVNode() } // set parent vnode.parent = _parentVnode return vnode } // shorthands used in render functions Vue.prototype._h = createElement // toString for mustaches Vue.prototype._s = _toString // number conversion Vue.prototype._n = toNumber // empty vnode Vue.prototype._e = emptyVNode // loose equal Vue.prototype._q = looseEqual // loose indexOf Vue.prototype._i = looseIndexOf // render static tree by index Vue.prototype._m = function renderStatic ( index, isInFor ) { var tree = this._staticTrees[index] // if has already-rendered static tree and not inside v-for, // we can reuse the same tree by doing a shallow clone. if (tree && !isInFor) { return Array.isArray(tree) ? cloneVNodes(tree) : cloneVNode(tree) } // otherwise, render a fresh tree. tree = this._staticTrees[index] = this.$options.staticRenderFns[index].call(this._renderProxy) if (Array.isArray(tree)) { for (var i = 0; i < tree.length; i++) { tree[i].isStatic = true tree[i].key = "__static__" + index + "_" + i } } else { tree.isStatic = true tree.key = "__static__" + index } return tree } // filter resolution helper var identity = function (_) { return _; } Vue.prototype._f = function resolveFilter (id) { return resolveAsset(this.$options, 'filters', id, true) || identity } // render v-for Vue.prototype._l = function renderList ( val, render ) { var ret, i, l, keys, key if (Array.isArray(val)) { ret = new Array(val.length) for (i = 0, l = val.length; i < l; i++) { ret[i] = render(val[i], i) } } else if (typeof val === 'number') { ret = new Array(val) for (i = 0; i < val; i++) { ret[i] = render(i + 1, i) } } else if (isObject(val)) { keys = Object.keys(val) ret = new Array(keys.length) for (i = 0, l = keys.length; i < l; i++) { key = keys[i] ret[i] = render(val[key], key, i) } } return ret } // renderSlot Vue.prototype._t = function ( name, fallback ) { var slotNodes = this.$slots[name] // warn duplicate slot usage if (slotNodes && "development" !== 'production') { slotNodes._rendered && warn( "Duplicate presence of slot \"" + name + "\" found in the same render tree " + "- this will likely cause render errors.", this ) slotNodes._rendered = true } return slotNodes || fallback } // apply v-bind object Vue.prototype._b = function bindProps ( data, value, asProp ) { if (value) { if (!isObject(value)) { "development" !== 'production' && warn( 'v-bind without argument expects an Object or Array value', this ) } else { if (Array.isArray(value)) { value = toObject(value) } for (var key in value) { if (key === 'class' || key === 'style') { data[key] = value[key] } else { var hash = asProp || config.mustUseProp(key) ? data.domProps || (data.domProps = {}) : data.attrs || (data.attrs = {}) hash[key] = value[key] } } } } return data } // expose v-on keyCodes Vue.prototype._k = function getKeyCodes (key) { return config.keyCodes[key] } } function resolveSlots ( renderChildren ) { var slots = {} if (!renderChildren) { return slots } var children = normalizeChildren(renderChildren) || [] var defaultSlot = [] var name, child for (var i = 0, l = children.length; i < l; i++) { child = children[i] if (child.data && (name = child.data.slot)) { delete child.data.slot var slot = (slots[name] || (slots[name] = [])) if (child.tag === 'template') { slot.push.apply(slot, child.children) } else { slot.push(child) } } else { defaultSlot.push(child) } } // ignore single whitespace if (defaultSlot.length && !( defaultSlot.length === 1 && (defaultSlot[0].text === ' ' || defaultSlot[0].isComment) )) { slots.default = defaultSlot } return slots } /* */ function initEvents (vm) { vm._events = Object.create(null) // init parent attached events var listeners = vm.$options._parentListeners var on = bind(vm.$on, vm) var off = bind(vm.$off, vm) vm._updateListeners = function (listeners, oldListeners) { updateListeners(listeners, oldListeners || {}, on, off) } if (listeners) { vm._updateListeners(listeners) } } function eventsMixin (Vue) { Vue.prototype.$on = function (event, fn) { var vm = this ;(vm._events[event] || (vm._events[event] = [])).push(fn) return vm } Vue.prototype.$once = function (event, fn) { var vm = this function on () { vm.$off(event, on) fn.apply(vm, arguments) } on.fn = fn vm.$on(event, on) return vm } Vue.prototype.$off = function (event, fn) { var vm = this // all if (!arguments.length) { vm._events = Object.create(null) return vm } // specific event var cbs = vm._events[event] if (!cbs) { return vm } if (arguments.length === 1) { vm._events[event] = null return vm } // specific handler var cb var i = cbs.length while (i--) { cb = cbs[i] if (cb === fn || cb.fn === fn) { cbs.splice(i, 1) break } } return vm } Vue.prototype.$emit = function (event) { var vm = this var cbs = vm._events[event] if (cbs) { cbs = cbs.length > 1 ? toArray(cbs) : cbs var args = toArray(arguments, 1) for (var i = 0, l = cbs.length; i < l; i++) { cbs[i].apply(vm, args) } } return vm } } /* */ var uid = 0 function initMixin (Vue) { Vue.prototype._init = function (options) { var vm = this // a uid vm._uid = uid++ // a flag to avoid this being observed vm._isVue = true // merge options if (options && options._isComponent) { // optimize internal component instantiation // since dynamic options merging is pretty slow, and none of the // internal component options needs special treatment. initInternalComponent(vm, options) } else { vm.$options = mergeOptions( resolveConstructorOptions(vm), options || {}, vm ) } /* istanbul ignore else */ if ("development" !== 'production') { initProxy(vm) } else {} // expose real self vm._self = vm initLifecycle(vm) initEvents(vm) callHook(vm, 'beforeCreate') initState(vm) callHook(vm, 'created') initRender(vm) } function initInternalComponent (vm, options) { var opts = vm.$options = Object.create(resolveConstructorOptions(vm)) // doing this because it's faster than dynamic enumeration. opts.parent = options.parent opts.propsData = options.propsData opts._parentVnode = options._parentVnode opts._parentListeners = options._parentListeners opts._renderChildren = options._renderChildren opts._componentTag = options._componentTag if (options.render) { opts.render = options.render opts.staticRenderFns = options.staticRenderFns } } function resolveConstructorOptions (vm) { var Ctor = vm.constructor var options = Ctor.options if (Ctor.super) { var superOptions = Ctor.super.options var cachedSuperOptions = Ctor.superOptions if (superOptions !== cachedSuperOptions) { // super option changed Ctor.superOptions = superOptions options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions) if (options.name) { options.components[options.name] = Ctor } } } return options } } function Vue (options) { this._init(options) } initMixin(Vue) stateMixin(Vue) eventsMixin(Vue) lifecycleMixin(Vue) renderMixin(Vue) var warn = noop var formatComponentName if ("development" !== 'production') { var hasConsole = typeof console !== 'undefined' warn = function (msg, vm) { if (hasConsole && (!config.silent)) { console.error("[Vue warn]: " + msg + " " + ( vm ? formatLocation(formatComponentName(vm)) : '' )) } } formatComponentName = function (vm) { if (vm.$root === vm) { return 'root instance' } var name = vm._isVue ? vm.$options.name || vm.$options._componentTag : vm.name return name ? ("component <" + name + ">") : "anonymous component" } var formatLocation = function (str) { if (str === 'anonymous component') { str += " - use the \"name\" option for better debugging messages." } return ("(found in " + str + ")") } } /* */ /** * Option overwriting strategies are functions that handle * how to merge a parent option value and a child option * value into the final value. */ var strats = config.optionMergeStrategies /** * Options with restrictions */ if ("development" !== 'production') { strats.el = strats.propsData = function (parent, child, vm, key) { if (!vm) { warn( "option \"" + key + "\" can only be used during instance " + 'creation with the `new` keyword.' ) } return defaultStrat(parent, child) } strats.name = function (parent, child, vm) { if (vm && child) { warn( 'options "name" can only be used as a component definition option, ' + 'not during instance creation.' ) } return defaultStrat(parent, child) } } /** * Helper that recursively merges two data objects together. */ function mergeData (to, from) { var key, toVal, fromVal for (key in from) { toVal = to[key] fromVal = from[key] if (!hasOwn(to, key)) { set(to, key, fromVal) } else if (isObject(toVal) && isObject(fromVal)) { mergeData(toVal, fromVal) } } return to } /** * Data */ strats.data = function ( parentVal, childVal, vm ) { if (!vm) { // in a Vue.extend merge, both should be functions if (!childVal) { return parentVal } if (typeof childVal !== 'function') { "development" !== 'production' && warn( 'The "data" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.', vm ) return parentVal } if (!parentVal) { return childVal } // when parentVal & childVal are both present, // we need to return a function that returns the // merged result of both functions... no need to // check if parentVal is a function here because // it has to be a function to pass previous merges. return function mergedDataFn () { return mergeData( childVal.call(this), parentVal.call(this) ) } } else if (parentVal || childVal) { return function mergedInstanceDataFn () { // instance merge var instanceData = typeof childVal === 'function' ? childVal.call(vm) : childVal var defaultData = typeof parentVal === 'function' ? parentVal.call(vm) : undefined if (instanceData) { return mergeData(instanceData, defaultData) } else { return defaultData } } } } /** * Hooks and param attributes are merged as arrays. */ function mergeHook ( parentVal, childVal ) { return childVal ? parentVal ? parentVal.concat(childVal) : Array.isArray(childVal) ? childVal : [childVal] : parentVal } config._lifecycleHooks.forEach(function (hook) { strats[hook] = mergeHook }) /** * Assets * * When a vm is present (instance creation), we need to do * a three-way merge between constructor options, instance * options and parent options. */ function mergeAssets (parentVal, childVal) { var res = Object.create(parentVal || null) return childVal ? extend(res, childVal) : res } config._assetTypes.forEach(function (type) { strats[type + 's'] = mergeAssets }) /** * Watchers. * * Watchers hashes should not overwrite one * another, so we merge them as arrays. */ strats.watch = function (parentVal, childVal) { /* istanbul ignore if */ 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] if (parent && !Array.isArray(parent)) { parent = [parent] } ret[key] = parent ? parent.concat(child) : [child] } return ret } /** * Other object hashes. */ strats.props = strats.methods = strats.computed = function (parentVal, childVal) { if (!childVal) { return parentVal } if (!parentVal) { return childVal } var ret = Object.create(null) extend(ret, 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. */ function normalizeComponents (options) { if (options.components) { var components = options.components var def for (var key in components) { var lower = key.toLowerCase() if (isBuiltInTag(lower) || config.isReservedTag(lower)) { "development" !== 'production' && warn( 'Do not use built-in or reserved HTML elements as component ' + 'id: ' + key ) continue } def = components[key] if (isPlainObject(def)) { components[key] = Vue.extend(def) } } } } /** * Ensure all props option syntax are normalized into the * Object-based format. */ function normalizeProps (options) { var props = options.props if (!props) { return } var res = {} var i, val, name if (Array.isArray(props)) { i = props.length while (i--) { val = props[i] if (typeof val === 'string') { name = camelize(val) res[name] = { type: null } } else if ("development" !== 'production') { warn('props must be strings when using array syntax.') } } } else if (isPlainObject(props)) { for (var key in props) { val = props[key] name = camelize(key) res[name] = isPlainObject(val) ? val : { type: val } } } options.props = res } /** * Normalize raw function directives into object format. */ function normalizeDirectives (options) { var dirs = options.directives if (dirs) { for (var key in dirs) { var def = dirs[key] if (typeof def === 'function') { dirs[key] = { bind: def, update: def } } } } } /** * Merge two option objects into a new one. * Core utility used in both instantiation and inheritance. */ function mergeOptions ( parent, child, vm ) { normalizeComponents(child) normalizeProps(child) normalizeDirectives(child) var extendsFrom = child.extends if (extendsFrom) { parent = typeof extendsFrom === 'function' ? mergeOptions(parent, extendsFrom.options, vm) : mergeOptions(parent, extendsFrom, vm) } if (child.mixins) { for (var i = 0, l = child.mixins.length; i < l; i++) { var mixin = child.mixins[i] if (mixin.prototype instanceof Vue) { mixin = mixin.options } parent = mergeOptions(parent, mixin, vm) } } var options = {} var key for (key in parent) { mergeField(key) } for (key in child) { if (!hasOwn(parent, key)) { mergeField(key) } } function mergeField (key) { var strat = strats[key] || defaultStrat options[key] = strat(parent[key], child[key], vm, key) } return options } /** * Resolve an asset. * This function is used because child instances need access * to assets defined in its ancestor chain. */ function resolveAsset ( options, type, id, warnMissing ) { /* istanbul ignore if */ if (typeof id !== 'string') { return } var assets = options[type] var res = assets[id] || // camelCase ID assets[camelize(id)] || // Pascal Case ID assets[capitalize(camelize(id))] if ("development" !== 'production' && warnMissing && !res) { warn( 'Failed to resolve ' + type.slice(0, -1) + ': ' + id, options ) } return res } /* */ function validateProp ( key, propOptions, propsData, vm ) { var prop = propOptions[key] var absent = !hasOwn(propsData, key) var value = propsData[key] // handle boolean props if (getType(prop.type) === 'Boolean') { if (absent && !hasOwn(prop, 'default')) { value = false } else if (value === '' || value === hyphenate(key)) { value = true } } // check default value if (value === undefined) { value = getPropDefaultValue(vm, prop, key) // since the default value is a fresh copy, // make sure to observe it. var prevShouldConvert = observerState.shouldConvert observerState.shouldConvert = true observe(value) observerState.shouldConvert = prevShouldConvert } if ("development" !== 'production') { assertProp(prop, key, value, vm, absent) } return value } /** * Get the default value of a prop. */ function getPropDefaultValue (vm, prop, name) { // no default, return undefined if (!hasOwn(prop, 'default')) { return undefined } var def = prop.default // warn against non-factory defaults for Object & Array if (isObject(def)) { "development" !== 'production' && warn( 'Invalid default value for prop "' + name + '": ' + 'Props with type Object/Array must use a factory function ' + 'to return the default value.', vm ) } // call factory function for non-Function types return typeof def === 'function' && prop.type !== Function ? def.call(vm) : def } /** * Assert whether a prop is valid. */ function assertProp ( prop, name, value, vm, absent ) { if (prop.required && absent) { warn( 'Missing required prop: "' + name + '"', vm ) return } if (value == null && !prop.required) { return } var type = prop.type var valid = !type || type === true var expectedTypes = [] if (type) { if (!Array.isArray(type)) { type = [type] } for (var i = 0; i < type.length && !valid; i++) { var assertedType = assertType(value, type[i]) expectedTypes.push(assertedType.expectedType) valid = assertedType.valid } } if (!valid) { warn( 'Invalid prop: type check failed for prop "' + name + '".' + ' Expected ' + expectedTypes.map(capitalize).join(', ') + ', got ' + Object.prototype.toString.call(value).slice(8, -1) + '.', vm ) return } var validator = prop.validator if (validator) { if (!validator(value)) { warn( 'Invalid prop: custom validator check failed for prop "' + name + '".', vm ) } } } /** * Assert the type of a value */ function assertType (value, type) { var valid var expectedType = getType(type) if (expectedType === 'String') { valid = typeof value === (expectedType = 'string') } else if (expectedType === 'Number') { valid = typeof value === (expectedType = 'number') } else if (expectedType === 'Boolean') { valid = typeof value === (expectedType = 'boolean') } else if (expectedType === 'Function') { valid = typeof value === (expectedType = 'function') } else if (expectedType === 'Object') { valid = isPlainObject(value) } else if (expectedType === 'Array') { valid = Array.isArray(value) } else { valid = value instanceof type } return { valid: valid, expectedType: expectedType } } /** * Use function string name to check built-in types, * because a simple equality check will fail when running * across different vms / iframes. */ function getType (fn) { var match = fn && fn.toString().match(/^\s*function (\w+)/) return match && match[1] } var util = Object.freeze({ defineReactive: defineReactive, _toString: _toString, toNumber: toNumber, makeMap: makeMap, isBuiltInTag: isBuiltInTag, remove: remove, hasOwn: hasOwn, isPrimitive: isPrimitive, cached: cached, camelize: camelize, capitalize: capitalize, hyphenate: hyphenate, bind: bind, toArray: toArray, extend: extend, isObject: isObject, isPlainObject: isPlainObject, toObject: toObject, noop: noop, no: no, genStaticKeys: genStaticKeys, looseEqual: looseEqual, looseIndexOf: looseIndexOf, isReserved: isReserved, def: def, parsePath: parsePath, hasProto: hasProto, inBrowser: inBrowser, UA: UA, isIE: isIE, isIE9: isIE9, isEdge: isEdge, isAndroid: isAndroid, devtools: devtools, nextTick: nextTick, get _Set () { return _Set; }, mergeOptions: mergeOptions, resolveAsset: resolveAsset, get warn () { return warn; }, get formatComponentName () { return formatComponentName; }, validateProp: validateProp }); /* */ function initUse (Vue) { Vue.use = function (plugin) { /* istanbul ignore if */ if (plugin.installed) { return } // 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) } plugin.installed = true return this } } /* */ function initMixin$1 (Vue) { Vue.mixin = function (mixin) { Vue.options = mergeOptions(Vue.options, mixin) } } /* */ function initExtend (Vue) { /** * Each instance constructor, including Vue, has a unique * cid. This enables us to create wrapped "child * constructors" for prototypal inheritance and cache them. */ Vue.cid = 0 var cid = 1 /** * Class inheritance */ Vue.extend = function (extendOptions) { extendOptions = extendOptions || {} var Super = this var isFirstExtend = Super.cid === 0 if (isFirstExtend && extendOptions._Ctor) { return extendOptions._Ctor } var name = extendOptions.name || Super.options.name if ("development" !== 'production') { if (!/^[a-zA-Z][\w-]*$/.test(name)) { warn( 'Invalid component name: "' + name + '". Component names ' + 'can only contain alphanumeric characaters and the hyphen.' ) name = null } } var Sub = function VueComponent (options) { this._init(options) } 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. config._assetTypes.forEach(function (type) { Sub[type] = Super[type] }) // enable recursive self-lookup if (name) { Sub.options.components[name] = Sub } // keep a reference to the super options at extension time. // later at instantiation we can check if Super's options have // been updated. Sub.superOptions = Super.options Sub.extendOptions = extendOptions // cache constructor if (isFirstExtend) { extendOptions._Ctor = Sub } return Sub } } /* */ function initAssetRegisters (Vue) { /** * Create asset registration methods. */ config._assetTypes.forEach(function (type) { Vue[type] = function ( id, definition ) { if (!definition) { return this.options[type + 's'][id] } else { /* istanbul ignore if */ if ("development" !== 'production') { if (type === 'component' && config.isReservedTag(id)) { warn( 'Do not use built-in or reserved HTML elements as component ' + 'id: ' + id ) } } if (type === 'component' && isPlainObject(definition)) { definition.name = definition.name || id definition = Vue.extend(definition) } if (type === 'directive' && typeof definition === 'function') { definition = { bind: definition, update: definition } } this.options[type + 's'][id] = definition return definition } } }) } var KeepAlive = { name: 'keep-alive', abstract: true, created: function created () { this.cache = Object.create(null) }, render: function render () { var vnode = getFirstComponentChild(this.$slots.default) if (vnode && vnode.componentOptions) { var opts = vnode.componentOptions var key = vnode.key == null // same constructor may get registered as different local components // so cid alone is not enough (#3269) ? opts.Ctor.cid + '::' + opts.tag : vnode.key if (this.cache[key]) { vnode.child = this.cache[key].child } else { this.cache[key] = vnode } vnode.data.keepAlive = true } return vnode }, destroyed: function destroyed () { var this$1 = this; for (var key in this.cache) { var vnode = this$1.cache[key] callHook(vnode.child, 'deactivated') vnode.child.$destroy() } } } var builtInComponents = { KeepAlive: KeepAlive } /* */ function initGlobalAPI (Vue) { // config var configDef = {} configDef.get = function () { return config; } if ("development" !== 'production') { configDef.set = function () { warn( 'Do not replace the Vue.config object, set individual fields instead.' ) } } Object.defineProperty(Vue, 'config', configDef) Vue.util = util Vue.set = set Vue.delete = del Vue.nextTick = nextTick Vue.options = Object.create(null) config._assetTypes.forEach(function (type) { Vue.options[type + 's'] = Object.create(null) }) extend(Vue.options.components, builtInComponents) initUse(Vue) initMixin$1(Vue) initExtend(Vue) initAssetRegisters(Vue) } initGlobalAPI(Vue) Object.defineProperty(Vue.prototype, '$isServer', { get: function () { return config._isServer; } }) Vue.version = '2.0.0-rc.7' /* */ // attributes that should be using props for binding var mustUseProp = makeMap('value,selected,checked,muted') var isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck') var isBooleanAttr = makeMap( 'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' + 'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' + 'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' + 'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' + 'required,reversed,scoped,seamless,selected,sortable,translate,' + 'truespeed,typemustmatch,visible' ) var isAttr = makeMap( 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,' + 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,' + 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,' + 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,' + 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,' + 'form,formaction,headers,
, or missing
. Bailing hydration and performing ' + 'full client-side render.' ) } } // either not server-rendered, or hydration failed. // create an empty node and replace it oldVnode = emptyNodeAt(oldVnode) } elm = oldVnode.elm parent = nodeOps.parentNode(elm) createElm(vnode, insertedVnodeQueue) // component root element replaced. // update parent placeholder node element. if (vnode.parent) { vnode.parent.elm = vnode.elm if (isPatchable(vnode)) { for (var i = 0; i < cbs.create.length; ++i) { cbs.create[i](emptyNode, vnode.parent) } } } if (parent !== null) { nodeOps.insertBefore(parent, vnode.elm, nodeOps.nextSibling(elm)) removeVnodes(parent, [oldVnode], 0, 0) } else if (isDef(oldVnode.tag)) { invokeDestroyHook(oldVnode) } } } invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch) return vnode.elm } } /* */ var directives = { create: function bindDirectives (oldVnode, vnode) { var hasInsert = false forEachDirective(oldVnode, vnode, function (def, dir) { callHook$1(def, dir, 'bind', vnode, oldVnode) if (def.inserted) { hasInsert = true } }) if (hasInsert) { mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', function () { applyDirectives(oldVnode, vnode, 'inserted') }) } }, update: function updateDirectives (oldVnode, vnode) { applyDirectives(oldVnode, vnode, 'update') // if old vnode has directives but new vnode doesn't // we need to teardown the directives on the old one. if (oldVnode.data.directives && !vnode.data.directives) { applyDirectives(oldVnode, oldVnode, 'unbind') } }, postpatch: function postupdateDirectives (oldVnode, vnode) { applyDirectives(oldVnode, vnode, 'componentUpdated') }, destroy: function unbindDirectives (vnode) { applyDirectives(vnode, vnode, 'unbind') } } var emptyModifiers = Object.create(null) function forEachDirective ( oldVnode, vnode, fn ) { var dirs = vnode.data.directives if (dirs) { for (var i = 0; i < dirs.length; i++) { var dir = dirs[i] var def = resolveAsset(vnode.context.$options, 'directives', dir.name, true) if (def) { var oldDirs = oldVnode && oldVnode.data.directives if (oldDirs) { dir.oldValue = oldDirs[i].value } if (!dir.modifiers) { dir.modifiers = emptyModifiers } fn(def, dir) } } } } function applyDirectives ( oldVnode, vnode, hook ) { forEachDirective(oldVnode, vnode, function (def, dir) { callHook$1(def, dir, hook, vnode, oldVnode) }) } function callHook$1 (def, dir, hook, vnode, oldVnode) { var fn = def && def[hook] if (fn) { fn(vnode.elm, dir, vnode, oldVnode) } } var baseModules = [ ref, directives ] /* */ function updateAttrs (oldVnode, vnode) { if (!oldVnode.data.attrs && !vnode.data.attrs) { return } var key, cur, old var elm = vnode.elm var oldAttrs = oldVnode.data.attrs || {} var attrs = vnode.data.attrs || {} // clone observed objects, as the user probably wants to mutate it if (attrs.__ob__) { attrs = vnode.data.attrs = extend({}, attrs) } for (key in attrs) { cur = attrs[key] old = oldAttrs[key] if (old !== cur) { setAttr(elm, key, cur) } } for (key in oldAttrs) { if (attrs[key] == null) { if (isXlink(key)) { elm.removeAttributeNS(xlinkNS, getXlinkProp(key)) } else if (!isEnumeratedAttr(key)) { elm.removeAttribute(key) } } } } function setAttr (el, key, value) { if (isBooleanAttr(key)) { // set attribute for blank value // e.g. if (isFalsyAttrValue(value)) { el.removeAttribute(key) } else { el.setAttribute(key, key) } } else if (isEnumeratedAttr(key)) { el.setAttribute(key, isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true') } else if (isXlink(key)) { if (isFalsyAttrValue(value)) { el.removeAttributeNS(xlinkNS, getXlinkProp(key)) } else { el.setAttributeNS(xlinkNS, key, value) } } else { if (isFalsyAttrValue(value)) { el.removeAttribute(key) } else { el.setAttribute(key, value) } } } var attrs = { create: updateAttrs, update: updateAttrs } /* */ function updateClass (oldVnode, vnode) { var el = vnode.elm var data = vnode.data var oldData = oldVnode.data if (!data.staticClass && !data.class && (!oldData || (!oldData.staticClass && !oldData.class))) { return } var cls = genClassForVnode(vnode) // handle transition classes var transitionClass = el._transitionClasses if (transitionClass) { cls = concat(cls, stringifyClass(transitionClass)) } // set the class if (cls !== el._prevClass) { el.setAttribute('class', cls) el._prevClass = cls } } var klass = { create: updateClass, update: updateClass } // skip type checking this file because we need to attach private properties // to elements function updateDOMListeners (oldVnode, vnode) { if (!oldVnode.data.on && !vnode.data.on) { return } var on = vnode.data.on || {} var oldOn = oldVnode.data.on || {} var add = vnode.elm._v_add || (vnode.elm._v_add = function (event, handler, capture) { vnode.elm.addEventListener(event, handler, capture) }) var remove = vnode.elm._v_remove || (vnode.elm._v_remove = function (event, handler) { vnode.elm.removeEventListener(event, handler) }) updateListeners(on, oldOn, add, remove) } var events = { create: updateDOMListeners, update: updateDOMListeners } /* */ function updateDOMProps (oldVnode, vnode) { if (!oldVnode.data.domProps && !vnode.data.domProps) { return } var key, cur var elm = vnode.elm var oldProps = oldVnode.data.domProps || {} var props = vnode.data.domProps || {} // clone observed objects, as the user probably wants to mutate it if (props.__ob__) { props = vnode.data.domProps = extend({}, props) } for (key in oldProps) { if (props[key] == null) { elm[key] = undefined } } for (key in props) { // ignore children if the node has textContent or innerHTML, // as these will throw away existing DOM nodes and cause removal errors // on subsequent patches (#3360) if ((key === 'textContent' || key === 'innerHTML') && vnode.children) { vnode.children.length = 0 } cur = props[key] if (key === 'value') { // store value as _value as well since // non-string values will be stringified elm._value = cur // avoid resetting cursor position when value is the same var strCur = cur == null ? '' : String(cur) if (elm.value !== strCur) { elm.value = strCur } } else { elm[key] = cur } } } var domProps = { create: updateDOMProps, update: updateDOMProps } /* */ var prefixes = ['Webkit', 'Moz', 'ms'] var testEl var normalize = cached(function (prop) { testEl = testEl || document.createElement('div') prop = camelize(prop) if (prop !== 'filter' && (prop in testEl.style)) { return prop } var upper = prop.charAt(0).toUpperCase() + prop.slice(1) for (var i = 0; i < prefixes.length; i++) { var prefixed = prefixes[i] + upper if (prefixed in testEl.style) { return prefixed } } }) function updateStyle (oldVnode, vnode) { if ((!oldVnode.data || !oldVnode.data.style) && !vnode.data.style) { return } var cur, name var el = vnode.elm var oldStyle = oldVnode.data.style || {} var style = vnode.data.style || {} // handle string if (typeof style === 'string') { el.style.cssText = style return } var needClone = style.__ob__ // handle array syntax if (Array.isArray(style)) { style = vnode.data.style = toObject(style) } // clone the style for future updates, // in case the user mutates the style object in-place. if (needClone) { style = vnode.data.style = extend({}, style) } for (name in oldStyle) { if (!style[name]) { el.style[normalize(name)] = '' } } for (name in style) { cur = style[name] if (cur !== oldStyle[name]) { // ie9 setting to null has no effect, must use empty string el.style[normalize(name)] = cur || '' } } } var style = { create: updateStyle, update: updateStyle } /* */ /** * Add class with compatibility for SVG since classList is not supported on * SVG elements in IE */ function addClass (el, cls) { /* istanbul ignore else */ if (el.classList) { if (cls.indexOf(' ') > -1) { cls.split(/\s+/).forEach(function (c) { return el.classList.add(c); }) } else { 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 SVG since classList is not supported on * SVG elements in IE */ function removeClass (el, cls) { /* istanbul ignore else */ if (el.classList) { if (cls.indexOf(' ') > -1) { cls.split(/\s+/).forEach(function (c) { return el.classList.remove(c); }) } else { 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()) } } /* */ var hasTransition = inBrowser && !isIE9 var TRANSITION = 'transition' var ANIMATION = 'animation' // Transition property/event sniffing var transitionProp = 'transition' var transitionEndEvent = 'transitionend' var animationProp = 'animation' var animationEndEvent = 'animationend' if (hasTransition) { /* istanbul ignore if */ if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) { transitionProp = 'WebkitTransition' transitionEndEvent = 'webkitTransitionEnd' } if (window.onanimationend === undefined && window.onwebkitanimationend !== undefined) { animationProp = 'WebkitAnimation' animationEndEvent = 'webkitAnimationEnd' } } var raf = (inBrowser && window.requestAnimationFrame) || setTimeout function nextFrame (fn) { raf(function () { raf(fn) }) } function addTransitionClass (el, cls) { (el._transitionClasses || (el._transitionClasses = [])).push(cls) addClass(el, cls) } function removeTransitionClass (el, cls) { if (el._transitionClasses) { remove(el._transitionClasses, cls) } removeClass(el, cls) } function whenTransitionEnds ( el, expectedType, cb ) { var ref = getTransitionInfo(el, expectedType); var type = ref.type; var timeout = ref.timeout; var propCount = ref.propCount; if (!type) { return cb() } var event = type === TRANSITION ? transitionEndEvent : animationEndEvent var ended = 0 var end = function () { el.removeEventListener(event, onEnd) cb() } var onEnd = function (e) { if (e.target === el) { if (++ended >= propCount) { end() } } } setTimeout(function () { if (ended < propCount) { end() } }, timeout + 1) el.addEventListener(event, onEnd) } var transformRE = /\b(transform|all)(,|$)/ function getTransitionInfo (el, expectedType) { var styles = window.getComputedStyle(el) var transitioneDelays = styles[transitionProp + 'Delay'].split(', ') var transitionDurations = styles[transitionProp + 'Duration'].split(', ') var transitionTimeout = getTimeout(transitioneDelays, transitionDurations) var animationDelays = styles[animationProp + 'Delay'].split(', ') var animationDurations = styles[animationProp + 'Duration'].split(', ') var animationTimeout = getTimeout(animationDelays, animationDurations) var type var timeout = 0 var propCount = 0 /* istanbul ignore if */ if (expectedType === TRANSITION) { if (transitionTimeout > 0) { type = TRANSITION timeout = transitionTimeout propCount = transitionDurations.length } } else if (expectedType === ANIMATION) { if (animationTimeout > 0) { type = ANIMATION timeout = animationTimeout propCount = animationDurations.length } } else { timeout = Math.max(transitionTimeout, animationTimeout) type = timeout > 0 ? transitionTimeout > animationTimeout ? TRANSITION : ANIMATION : null propCount = type ? type === TRANSITION ? transitionDurations.length : animationDurations.length : 0 } var hasTransform = type === TRANSITION && transformRE.test(styles[transitionProp + 'Property']) return { type: type, timeout: timeout, propCount: propCount, hasTransform: hasTransform } } function getTimeout (delays, durations) { return Math.max.apply(null, durations.map(function (d, i) { return toMs(d) + toMs(delays[i]) })) } function toMs (s) { return Number(s.slice(0, -1)) * 1000 } /* */ function enter (vnode) { var el = vnode.elm // call leave callback now if (el._leaveCb) { el._leaveCb.cancelled = true el._leaveCb() } var data = resolveTransition(vnode.data.transition) if (!data) { return } /* istanbul ignore if */ if (el._enterCb || el.nodeType !== 1) { return } var css = data.css; var type = data.type; var enterClass = data.enterClass; var enterActiveClass = data.enterActiveClass; var appearClass = data.appearClass; var appearActiveClass = data.appearActiveClass; var beforeEnter = data.beforeEnter; var enter = data.enter; var afterEnter = data.afterEnter; var enterCancelled = data.enterCancelled; var beforeAppear = data.beforeAppear; var appear = data.appear; var afterAppear = data.afterAppear; var appearCancelled = data.appearCancelled; // activeInstance will always be the