Showing content from https://unpkg.com/vue@2.6.0/dist/vue.esm.browser.js below:
' } const options = typeof vm === 'function' && vm.cid != null ? vm.options : vm._isVue ? vm.$options || vm.constructor.options : vm; let name = options.name || options._componentTag; const file = options.__file; if (!name && file) { const match = file.match(/([^/\\]+)\.vue$/); name = match && match[1]; } return ( (name ? `<${classify(name)}>` : ` `) + (file && includeFile !== false ? ` at ${file}` : '') ) }; const repeat = (str, n) => { let res = ''; while (n) { if (n % 2 === 1) res += str; if (n > 1) str += str; n >>= 1; } return res }; generateComponentTrace = vm => { if (vm._isVue && vm.$parent) { const tree = []; let currentRecursiveSequence = 0; while (vm) { if (tree.length > 0) { const last = tree[tree.length - 1]; if (last.constructor === vm.constructor) { currentRecursiveSequence++; vm = vm.$parent; continue } else if (currentRecursiveSequence > 0) { tree[tree.length - 1] = [last, currentRecursiveSequence]; currentRecursiveSequence = 0; } } tree.push(vm); vm = vm.$parent; } return '\n\nfound in\n\n' + tree .map((vm, i) => `${ i === 0 ? '---> ' : repeat(' ', 5 + i * 2) }${ Array.isArray(vm) ? `${formatComponentName(vm[0])}... (${vm[1]} recursive calls)` : formatComponentName(vm) }`) .join('\n') } else { return `\n\n(found in ${formatComponentName(vm)})` } }; } /* */ let uid = 0; /** * A dep is an observable that can have multiple * directives subscribing to it. */ class Dep { constructor () { this.id = uid++; this.subs = []; } addSub (sub) { this.subs.push(sub); } removeSub (sub) { remove(this.subs, sub); } depend () { if (Dep.target) { Dep.target.addDep(this); } } notify () { // stabilize the subscriber list first const subs = this.subs.slice(); if (!config.async) { // subs aren't sorted in scheduler if not running async // we need to sort them now to make sure they fire in correct // order subs.sort((a, b) => a.id - b.id); } for (let i = 0, l = subs.length; i < l; i++) { subs[i].update(); } } } // The current target watcher being evaluated. // This is globally unique because only one watcher // can be evaluated at a time. Dep.target = null; const targetStack = []; function pushTarget (target) { targetStack.push(target); Dep.target = target; } function popTarget () { targetStack.pop(); Dep.target = targetStack[targetStack.length - 1]; } /* */ class VNode { // rendered in this component's scope // component instance // component placeholder node // strictly internal // contains raw HTML? (server only) // hoisted static node // necessary for enter transition check // empty comment placeholder? // is a cloned node? // is a v-once node? // async component factory function // real context vm for functional nodes // for SSR caching // used to store functional render context for devtools // functional scope id support constructor ( tag, data, children, text, elm, context, componentOptions, asyncFactory ) { this.tag = tag; this.data = data; this.children = children; this.text = text; this.elm = elm; this.ns = undefined; this.context = context; this.fnContext = undefined; this.fnOptions = undefined; this.fnScopeId = undefined; this.key = data && data.key; this.componentOptions = componentOptions; this.componentInstance = undefined; this.parent = undefined; this.raw = false; this.isStatic = false; this.isRootInsert = true; this.isComment = false; this.isCloned = false; this.isOnce = false; this.asyncFactory = asyncFactory; this.asyncMeta = undefined; this.isAsyncPlaceholder = false; } // DEPRECATED: alias for componentInstance for backwards compat. /* istanbul ignore next */ get child () { return this.componentInstance } } const createEmptyVNode = (text = '') => { const node = new VNode(); node.text = text; node.isComment = true; return node }; function createTextVNode (val) { return new VNode(undefined, undefined, undefined, String(val)) } // 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) { const cloned = new VNode( vnode.tag, vnode.data, // #7975 // clone children array to avoid mutating original in case of cloning // a child. vnode.children && vnode.children.slice(), vnode.text, vnode.elm, vnode.context, vnode.componentOptions, vnode.asyncFactory ); cloned.ns = vnode.ns; cloned.isStatic = vnode.isStatic; cloned.key = vnode.key; cloned.isComment = vnode.isComment; cloned.fnContext = vnode.fnContext; cloned.fnOptions = vnode.fnOptions; cloned.fnScopeId = vnode.fnScopeId; cloned.asyncMeta = vnode.asyncMeta; cloned.isCloned = true; return cloned } /* * not type checking this file because flow doesn't play well with * dynamically accessing methods on Array prototype */ const arrayProto = Array.prototype; const arrayMethods = Object.create(arrayProto); const methodsToPatch = [ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ]; /** * Intercept mutating methods and emit events */ methodsToPatch.forEach(function (method) { // cache original method const original = arrayProto[method]; def(arrayMethods, method, function mutator (...args) { const result = original.apply(this, args); const ob = this.__ob__; let inserted; switch (method) { case 'push': case 'unshift': inserted = args; break case 'splice': inserted = args.slice(2); break } if (inserted) ob.observeArray(inserted); // notify change ob.dep.notify(); return result }); }); /* */ const arrayKeys = Object.getOwnPropertyNames(arrayMethods); /** * In some cases we may want to disable observation inside a component's * update computation. */ let shouldObserve = true; function toggleObserving (value) { shouldObserve = value; } /** * Observer class that is attached to each observed * object. Once attached, the observer converts the target * object's property keys into getter/setters that * collect dependencies and dispatch updates. */ class Observer { // number of vms that have this object as root $data constructor (value) { this.value = value; this.dep = new Dep(); this.vmCount = 0; def(value, '__ob__', this); if (Array.isArray(value)) { if (hasProto) { protoAugment(value, arrayMethods); } else { copyAugment(value, arrayMethods, arrayKeys); } this.observeArray(value); } else { this.walk(value); } } /** * Walk through all properties and convert them into * getter/setters. This method should only be called when * value type is Object. */ walk (obj) { const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { defineReactive$$1(obj, keys[i]); } } /** * Observe a list of Array items. */ observeArray (items) { for (let i = 0, l = items.length; i < l; i++) { observe(items[i]); } } } // helpers /** * Augment a 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 a target Object or Array by defining * hidden properties. */ /* istanbul ignore next */ function copyAugment (target, src, keys) { for (let i = 0, l = keys.length; i < l; i++) { const 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, asRootData) { if (!isObject(value) || value instanceof VNode) { return } let ob; if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { ob = value.__ob__; } else if ( shouldObserve && !isServerRendering() && (Array.isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue ) { ob = new Observer(value); } if (asRootData && ob) { ob.vmCount++; } return ob } /** * Define a reactive property on an Object. */ function defineReactive$$1 ( obj, key, val, customSetter, shallow ) { const dep = new Dep(); const property = Object.getOwnPropertyDescriptor(obj, key); if (property && property.configurable === false) { return } // cater for pre-defined getter/setters const getter = property && property.get; const setter = property && property.set; if ((!getter || setter) && arguments.length === 2) { val = obj[key]; } let childOb = !shallow && observe(val); Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () { const value = getter ? getter.call(obj) : val; if (Dep.target) { dep.depend(); if (childOb) { childOb.dep.depend(); if (Array.isArray(value)) { dependArray(value); } } } return value }, set: function reactiveSetter (newVal) { const value = getter ? getter.call(obj) : val; /* eslint-disable no-self-compare */ if (newVal === value || (newVal !== newVal && value !== value)) { return } /* eslint-enable no-self-compare */ if (customSetter) { customSetter(); } // #7981: for accessor properties without setter if (getter && !setter) return if (setter) { setter.call(obj, newVal); } else { val = newVal; } childOb = !shallow && 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 (target, key, val) { if (isUndef(target) || isPrimitive(target) ) { warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target)}`); } if (Array.isArray(target) && isValidArrayIndex(key)) { target.length = Math.max(target.length, key); target.splice(key, 1, val); return val } if (key in target && !(key in Object.prototype)) { target[key] = val; return val } const ob = (target).__ob__; if (target._isVue || (ob && ob.vmCount)) { warn( 'Avoid adding reactive properties to a Vue instance or its root $data ' + 'at runtime - declare it upfront in the data option.' ); return val } if (!ob) { target[key] = val; return val } defineReactive$$1(ob.value, key, val); ob.dep.notify(); return val } /** * Delete a property and trigger change if necessary. */ function del (target, key) { if (isUndef(target) || isPrimitive(target) ) { warn(`Cannot delete reactive property on undefined, null, or primitive value: ${(target)}`); } if (Array.isArray(target) && isValidArrayIndex(key)) { target.splice(key, 1); return } const ob = (target).__ob__; if (target._isVue || (ob && ob.vmCount)) { warn( 'Avoid deleting properties on a Vue instance or its root $data ' + '- just set it to null.' ); return } if (!hasOwn(target, key)) { return } delete target[key]; if (!ob) { return } ob.dep.notify(); } /** * Collect dependencies on array elements when the array is touched, since * we cannot intercept array element access like property getters. */ function dependArray (value) { for (let e, i = 0, l = value.length; i < l; i++) { e = value[i]; e && e.__ob__ && e.__ob__.dep.depend(); if (Array.isArray(e)) { dependArray(e); } } } /* */ /** * Option overwriting strategies are functions that handle * how to merge a parent option value and a child option * value into the final value. */ const strats = config.optionMergeStrategies; /** * Options with restrictions */ { 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) }; } /** * Helper that recursively merges two data objects together. */ function mergeData (to, from) { if (!from) return to let key, toVal, fromVal; const keys = hasSymbol ? Reflect.ownKeys(from) : Object.keys(from); for (let i = 0; i < keys.length; i++) { key = keys[i]; // in case the object is already observed... if (key === '__ob__') continue toVal = to[key]; fromVal = from[key]; if (!hasOwn(to, key)) { set(to, key, fromVal); } else if ( toVal !== fromVal && isPlainObject(toVal) && isPlainObject(fromVal) ) { mergeData(toVal, fromVal); } } return to } /** * Data */ function mergeDataOrFn ( parentVal, childVal, vm ) { if (!vm) { // in a Vue.extend merge, both should be functions if (!childVal) { 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( typeof childVal === 'function' ? childVal.call(this, this) : childVal, typeof parentVal === 'function' ? parentVal.call(this, this) : parentVal ) } } else { return function mergedInstanceDataFn () { // instance merge const instanceData = typeof childVal === 'function' ? childVal.call(vm, vm) : childVal; const defaultData = typeof parentVal === 'function' ? parentVal.call(vm, vm) : parentVal; if (instanceData) { return mergeData(instanceData, defaultData) } else { return defaultData } } } } strats.data = function ( parentVal, childVal, vm ) { if (!vm) { if (childVal && typeof childVal !== 'function') { warn( 'The "data" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.', vm ); return parentVal } return mergeDataOrFn(parentVal, childVal) } return mergeDataOrFn(parentVal, childVal, vm) }; /** * Hooks and props are merged as arrays. */ function mergeHook ( parentVal, childVal ) { const res = childVal ? parentVal ? parentVal.concat(childVal) : Array.isArray(childVal) ? childVal : [childVal] : parentVal; return res ? dedupeHooks(res) : res } function dedupeHooks (hooks) { const res = []; for (let i = 0; i < hooks.length; i++) { if (res.indexOf(hooks[i]) === -1) { res.push(hooks[i]); } } return res } LIFECYCLE_HOOKS.forEach(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, vm, key ) { const res = Object.create(parentVal || null); if (childVal) { assertObjectType(key, childVal, vm); return extend(res, childVal) } else { return res } } ASSET_TYPES.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, vm, key ) { // work around Firefox's Object.prototype.watch... if (parentVal === nativeWatch) parentVal = undefined; if (childVal === nativeWatch) childVal = undefined; /* istanbul ignore if */ if (!childVal) return Object.create(parentVal || null) { assertObjectType(key, childVal, vm); } if (!parentVal) return childVal const ret = {}; extend(ret, parentVal); for (const key in childVal) { let parent = ret[key]; const child = childVal[key]; if (parent && !Array.isArray(parent)) { parent = [parent]; } ret[key] = parent ? parent.concat(child) : Array.isArray(child) ? child : [child]; } return ret }; /** * Other object hashes. */ strats.props = strats.methods = strats.inject = strats.computed = function ( parentVal, childVal, vm, key ) { if (childVal && "development" !== 'production') { assertObjectType(key, childVal, vm); } if (!parentVal) return childVal const ret = Object.create(null); extend(ret, parentVal); if (childVal) extend(ret, childVal); return ret }; strats.provide = mergeDataOrFn; /** * Default strategy. */ const defaultStrat = function (parentVal, childVal) { return childVal === undefined ? parentVal : childVal }; /** * Validate component names */ function checkComponents (options) { for (const key in options.components) { validateComponentName(key); } } function validateComponentName (name) { if (!new RegExp(`^[a-zA-Z][\\-\\.0-9_${unicodeLetters}]*$`).test(name)) { warn( 'Invalid component name: "' + name + '". Component names ' + 'should conform to valid custom element name in html5 specification.' ); } if (isBuiltInTag(name) || config.isReservedTag(name)) { warn( 'Do not use built-in or reserved HTML elements as component ' + 'id: ' + name ); } } /** * Ensure all props option syntax are normalized into the * Object-based format. */ function normalizeProps (options, vm) { const props = options.props; if (!props) return const res = {}; let 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 { warn('props must be strings when using array syntax.'); } } } else if (isPlainObject(props)) { for (const key in props) { val = props[key]; name = camelize(key); res[name] = isPlainObject(val) ? val : { type: val }; } } else { warn( `Invalid value for option "props": expected an Array or an Object, ` + `but got ${toRawType(props)}.`, vm ); } options.props = res; } /** * Normalize all injections into Object-based format */ function normalizeInject (options, vm) { const inject = options.inject; if (!inject) return const normalized = options.inject = {}; if (Array.isArray(inject)) { for (let i = 0; i < inject.length; i++) { normalized[inject[i]] = { from: inject[i] }; } } else if (isPlainObject(inject)) { for (const key in inject) { const val = inject[key]; normalized[key] = isPlainObject(val) ? extend({ from: key }, val) : { from: val }; } } else { warn( `Invalid value for option "inject": expected an Array or an Object, ` + `but got ${toRawType(inject)}.`, vm ); } } /** * Normalize raw function directives into object format. */ function normalizeDirectives (options) { const dirs = options.directives; if (dirs) { for (const key in dirs) { const def$$1 = dirs[key]; if (typeof def$$1 === 'function') { dirs[key] = { bind: def$$1, update: def$$1 }; } } } } function assertObjectType (name, value, vm) { if (!isPlainObject(value)) { warn( `Invalid value for option "${name}": expected an Object, ` + `but got ${toRawType(value)}.`, vm ); } } /** * Merge two option objects into a new one. * Core utility used in both instantiation and inheritance. */ function mergeOptions ( parent, child, vm ) { { checkComponents(child); } if (typeof child === 'function') { child = child.options; } normalizeProps(child, vm); normalizeInject(child, vm); normalizeDirectives(child); // Apply extends and mixins on the child options, // but only if it is a raw options object that isn't // the result of another mergeOptions call. // Only merged options has the _base property. if (!child._base) { if (child.extends) { parent = mergeOptions(parent, child.extends, vm); } if (child.mixins) { for (let i = 0, l = child.mixins.length; i < l; i++) { parent = mergeOptions(parent, child.mixins[i], vm); } } } const options = {}; let key; for (key in parent) { mergeField(key); } for (key in child) { if (!hasOwn(parent, key)) { mergeField(key); } } function mergeField (key) { const 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 } const assets = options[type]; // check local registration variations first if (hasOwn(assets, id)) return assets[id] const camelizedId = camelize(id); if (hasOwn(assets, camelizedId)) return assets[camelizedId] const PascalCaseId = capitalize(camelizedId); if (hasOwn(assets, PascalCaseId)) return assets[PascalCaseId] // fallback to prototype chain const res = assets[id] || assets[camelizedId] || assets[PascalCaseId]; if (warnMissing && !res) { warn( 'Failed to resolve ' + type.slice(0, -1) + ': ' + id, options ); } return res } /* */ function validateProp ( key, propOptions, propsData, vm ) { const prop = propOptions[key]; const absent = !hasOwn(propsData, key); let value = propsData[key]; // boolean casting const booleanIndex = getTypeIndex(Boolean, prop.type); if (booleanIndex > -1) { if (absent && !hasOwn(prop, 'default')) { value = false; } else if (value === '' || value === hyphenate(key)) { // only cast empty string / same name to boolean if // boolean has higher priority const stringIndex = getTypeIndex(String, prop.type); if (stringIndex < 0 || booleanIndex < stringIndex) { 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. const prevShouldObserve = shouldObserve; toggleObserving(true); observe(value); toggleObserving(prevShouldObserve); } { assertProp(prop, key, value, vm, absent); } return value } /** * Get the default value of a prop. */ function getPropDefaultValue (vm, prop, key) { // no default, return undefined if (!hasOwn(prop, 'default')) { return undefined } const def = prop.default; // warn against non-factory defaults for Object & Array if (isObject(def)) { warn( 'Invalid default value for prop "' + key + '": ' + 'Props with type Object/Array must use a factory function ' + 'to return the default value.', vm ); } // the raw prop value was also undefined from previous render, // return previous default value to avoid unnecessary watcher trigger if (vm && vm.$options.propsData && vm.$options.propsData[key] === undefined && vm._props[key] !== undefined ) { return vm._props[key] } // call factory function for non-Function types // a value is Function if its prototype is function even across different execution context return typeof def === 'function' && getType(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 } let type = prop.type; let valid = !type || type === true; const expectedTypes = []; if (type) { if (!Array.isArray(type)) { type = [type]; } for (let i = 0; i < type.length && !valid; i++) { const assertedType = assertType(value, type[i]); expectedTypes.push(assertedType.expectedType || ''); valid = assertedType.valid; } } if (!valid) { warn( getInvalidTypeMessage(name, value, expectedTypes), vm ); return } const validator = prop.validator; if (validator) { if (!validator(value)) { warn( 'Invalid prop: custom validator check failed for prop "' + name + '".', vm ); } } } const simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/; function assertType (value, type) { let valid; const expectedType = getType(type); if (simpleCheckRE.test(expectedType)) { const t = typeof value; valid = t === expectedType.toLowerCase(); // for primitive wrapper objects if (!valid && t === 'object') { valid = value instanceof type; } } else if (expectedType === 'Object') { valid = isPlainObject(value); } else if (expectedType === 'Array') { valid = Array.isArray(value); } else { valid = value instanceof type; } return { valid, 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) { const match = fn && fn.toString().match(/^\s*function (\w+)/); return match ? match[1] : '' } function isSameType (a, b) { return getType(a) === getType(b) } function getTypeIndex (type, expectedTypes) { if (!Array.isArray(expectedTypes)) { return isSameType(expectedTypes, type) ? 0 : -1 } for (let i = 0, len = expectedTypes.length; i < len; i++) { if (isSameType(expectedTypes[i], type)) { return i } } return -1 } function getInvalidTypeMessage (name, value, expectedTypes) { let message = `Invalid prop: type check failed for prop "${name}".` + ` Expected ${expectedTypes.map(capitalize).join(', ')}`; const expectedType = expectedTypes[0]; const receivedType = toRawType(value); const expectedValue = styleValue(value, expectedType); const receivedValue = styleValue(value, receivedType); // check if we need to specify expected value if (expectedTypes.length === 1 && isExplicable(expectedType) && !isBoolean(expectedType, receivedType)) { message += ` with value ${expectedValue}`; } message += `, got ${receivedType} `; // check if we need to specify received value if (isExplicable(receivedType)) { message += `with value ${receivedValue}.`; } return message } function styleValue (value, type) { if (type === 'String') { return `"${value}"` } else if (type === 'Number') { return `${Number(value)}` } else { return `${value}` } } function isExplicable (value) { const explicitTypes = ['string', 'number', 'boolean']; return explicitTypes.some(elem => value.toLowerCase() === elem) } function isBoolean (...args) { return args.some(elem => elem.toLowerCase() === 'boolean') } /* */ function handleError (err, vm, info) { if (vm) { let cur = vm; while ((cur = cur.$parent)) { const hooks = cur.$options.errorCaptured; if (hooks) { for (let i = 0; i < hooks.length; i++) { try { const capture = hooks[i].call(cur, err, vm, info) === false; if (capture) return } catch (e) { globalHandleError(e, cur, 'errorCaptured hook'); } } } } } globalHandleError(err, vm, info); } function invokeWithErrorHandling ( handler, context, args, vm, info ) { let res; try { res = args ? handler.apply(context, args) : handler.call(context); if (isPromise(res)) { res.catch(e => handleError(e, vm, info + ` (Promise/async)`)); } } catch (e) { handleError(e, vm, info); } return res } function globalHandleError (err, vm, info) { if (config.errorHandler) { try { return config.errorHandler.call(null, err, vm, info) } catch (e) { logError(e, null, 'config.errorHandler'); } } logError(err, vm, info); } function logError (err, vm, info) { { warn(`Error in ${info}: "${err.toString()}"`, vm); } /* istanbul ignore else */ if ((inBrowser || inWeex) && typeof console !== 'undefined') { console.error(err); } else { throw err } } /* */ let isUsingMicroTask = false; const callbacks = []; let pending = false; function flushCallbacks () { pending = false; const copies = callbacks.slice(0); callbacks.length = 0; for (let i = 0; i < copies.length; i++) { copies[i](); } } // Here we have async deferring wrappers using microtasks. // In 2.5 we used (macro) tasks (in combination with microtasks). // However, it has subtle problems when state is changed right before repaint // (e.g. #6813, out-in transitions). // Also, using (macro) tasks in event handler would cause some weird behaviors // that cannot be circumvented (e.g. #7109, #7153, #7546, #7834, #8109). // So we now use microtasks everywhere, again. // A major drawback of this tradeoff is that there are some scenarios // where microtasks have too high a priority and fire in between supposedly // sequential events (e.g. #4521, #6690, which have workarounds) // or even between bubbling of the same event (#6566). let timerFunc; // The nextTick behavior leverages the microtask queue, which can be accessed // via either native Promise.then or MutationObserver. // MutationObserver has wider support, however it is seriously bugged in // UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It // completely stops working after triggering a few times... so, if native // Promise is available, we will use it: /* istanbul ignore next, $flow-disable-line */ if (typeof Promise !== 'undefined' && isNative(Promise)) { const p = Promise.resolve(); timerFunc = () => { p.then(flushCallbacks); // In problematic UIWebViews, Promise.then doesn't completely break, but // it can get stuck in a weird state where callbacks are pushed into the // microtask queue but the queue isn't being flushed, until the browser // needs to do some other work, e.g. handle a timer. Therefore we can // "force" the microtask queue to be flushed by adding an empty timer. if (isIOS) setTimeout(noop); }; isUsingMicroTask = true; } else if (!isIE && typeof MutationObserver !== 'undefined' && ( isNative(MutationObserver) || // PhantomJS and iOS 7.x MutationObserver.toString() === '[object MutationObserverConstructor]' )) { // Use MutationObserver where native Promise is not available, // e.g. PhantomJS, iOS7, Android 4.4 // (#6466 MutationObserver is unreliable in IE11) let counter = 1; const observer = new MutationObserver(flushCallbacks); const textNode = document.createTextNode(String(counter)); observer.observe(textNode, { characterData: true }); timerFunc = () => { counter = (counter + 1) % 2; textNode.data = String(counter); }; isUsingMicroTask = true; } else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { // Fallback to setImmediate. // Techinically it leverages the (macro) task queue, // but it is still a better choice than setTimeout. timerFunc = () => { setImmediate(flushCallbacks); }; } else { // Fallback to setTimeout. timerFunc = () => { setTimeout(flushCallbacks, 0); }; } function nextTick (cb, ctx) { let _resolve; callbacks.push(() => { if (cb) { try { cb.call(ctx); } catch (e) { handleError(e, ctx, 'nextTick'); } } else if (_resolve) { _resolve(ctx); } }); if (!pending) { pending = true; timerFunc(); } // $flow-disable-line if (!cb && typeof Promise !== 'undefined') { return new Promise(resolve => { _resolve = resolve; }) } } /* */ let mark; let measure; { const perf = inBrowser && window.performance; /* istanbul ignore if */ if ( perf && perf.mark && perf.measure && perf.clearMarks && perf.clearMeasures ) { mark = tag => perf.mark(tag); measure = (name, startTag, endTag) => { perf.measure(name, startTag, endTag); perf.clearMarks(startTag); perf.clearMarks(endTag); // perf.clearMeasures(name) }; } } /* not type checking this file because flow doesn't play well with Proxy */ let initProxy; { const 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 ); const warnNonPresent = (target, key) => { warn( `Property or method "${key}" is not defined on the instance but ` + 'referenced during render. Make sure that this property is reactive, ' + 'either in the data option, or for class-based components, by ' + 'initializing the property. ' + 'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.', target ); }; const warnReservedPrefix = (target, key) => { warn( `Property "${key}" must be accessed with "$data.${key}" because ` + 'properties starting with "$" or "_" are not proxied in the Vue instance to ' + 'prevent conflicts with Vue internals' + 'See: https://vuejs.org/v2/api/#data', target ); }; const hasProxy = typeof Proxy !== 'undefined' && isNative(Proxy); if (hasProxy) { const isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact'); config.keyCodes = new Proxy(config.keyCodes, { set (target, key, value) { if (isBuiltInModifier(key)) { warn(`Avoid overwriting built-in modifier in config.keyCodes: .${key}`); return false } else { target[key] = value; return true } } }); } const hasHandler = { has (target, key) { const has = key in target; const isAllowed = allowedGlobals(key) || (typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data)); if (!has && !isAllowed) { if (key in target.$data) warnReservedPrefix(target, key); else warnNonPresent(target, key); } return has || !isAllowed } }; const getHandler = { get (target, key) { if (typeof key === 'string' && !(key in target)) { if (key in target.$data) warnReservedPrefix(target, key); else warnNonPresent(target, key); } return target[key] } }; initProxy = function initProxy (vm) { if (hasProxy) { // determine which proxy handler to use const options = vm.$options; const handlers = options.render && options.render._withStripped ? getHandler : hasHandler; vm._renderProxy = new Proxy(vm, handlers); } else { vm._renderProxy = vm; } }; } /* */ const seenObjects = new _Set(); /** * Recursively traverse an object to evoke all converted * getters, so that every nested property inside the object * is collected as a "deep" dependency. */ function traverse (val) { _traverse(val, seenObjects); seenObjects.clear(); } function _traverse (val, seen) { let i, keys; const isA = Array.isArray(val); if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) { return } if (val.__ob__) { const depId = val.__ob__.dep.id; if (seen.has(depId)) { return } seen.add(depId); } if (isA) { i = val.length; while (i--) _traverse(val[i], seen); } else { keys = Object.keys(val); i = keys.length; while (i--) _traverse(val[keys[i]], seen); } } /* */ const normalizeEvent = cached((name) => { const passive = name.charAt(0) === '&'; name = passive ? name.slice(1) : name; const once$$1 = name.charAt(0) === '~'; // Prefixed last, checked first name = once$$1 ? name.slice(1) : name; const capture = name.charAt(0) === '!'; name = capture ? name.slice(1) : name; return { name, once: once$$1, capture, passive } }); function createFnInvoker (fns, vm) { function invoker () { const fns = invoker.fns; if (Array.isArray(fns)) { const cloned = fns.slice(); for (let i = 0; i < cloned.length; i++) { invokeWithErrorHandling(cloned[i], null, arguments, vm, `v-on handler`); } } else { // return handler return value for single handlers return invokeWithErrorHandling(fns, null, arguments, vm, `v-on handler`) } } invoker.fns = fns; return invoker } function updateListeners ( on, oldOn, add, remove$$1, createOnceHandler, vm ) { let name, def$$1, cur, old, event; for (name in on) { def$$1 = cur = on[name]; old = oldOn[name]; event = normalizeEvent(name); if (isUndef(cur)) { warn( `Invalid handler for event "${event.name}": got ` + String(cur), vm ); } else if (isUndef(old)) { if (isUndef(cur.fns)) { cur = on[name] = createFnInvoker(cur, vm); } if (isTrue(event.once)) { cur = on[name] = createOnceHandler(event.name, cur, event.capture); } add(event.name, cur, event.capture, event.passive, event.params); } else if (cur !== old) { old.fns = cur; on[name] = old; } } for (name in oldOn) { if (isUndef(on[name])) { event = normalizeEvent(name); remove$$1(event.name, oldOn[name], event.capture); } } } /* */ function mergeVNodeHook (def, hookKey, hook) { if (def instanceof VNode) { def = def.data.hook || (def.data.hook = {}); } let invoker; const oldHook = def[hookKey]; function wrappedHook () { hook.apply(this, arguments); // important: remove merged hook to ensure it's called only once // and prevent memory leak remove(invoker.fns, wrappedHook); } if (isUndef(oldHook)) { // no existing hook invoker = createFnInvoker([wrappedHook]); } else { /* istanbul ignore if */ if (isDef(oldHook.fns) && isTrue(oldHook.merged)) { // already a merged invoker invoker = oldHook; invoker.fns.push(wrappedHook); } else { // existing plain hook invoker = createFnInvoker([oldHook, wrappedHook]); } } invoker.merged = true; def[hookKey] = invoker; } /* */ function extractPropsFromVNodeData ( data, Ctor, tag ) { // we are only extracting raw values here. // validation and default values are handled in the child // component itself. const propOptions = Ctor.options.props; if (isUndef(propOptions)) { return } const res = {}; const { attrs, props } = data; if (isDef(attrs) || isDef(props)) { for (const key in propOptions) { const altKey = hyphenate(key); { const keyInLowerCase = key.toLowerCase(); if ( key !== keyInLowerCase && attrs && hasOwn(attrs, keyInLowerCase) ) { tip( `Prop "${keyInLowerCase}" is passed to component ` + `${formatComponentName(tag || Ctor)}, but the declared prop name is` + ` "${key}". ` + `Note that HTML attributes are case-insensitive and camelCased ` + `props need to use their kebab-case equivalents when using in-DOM ` + `templates. You should probably use "${altKey}" instead of "${key}".` ); } } checkProp(res, props, key, altKey, true) || checkProp(res, attrs, key, altKey, false); } } return res } function checkProp ( res, hash, key, altKey, preserve ) { if (isDef(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 } /* */ // The template compiler attempts to minimize the need for normalization by // statically analyzing the template at compile time. // // For plain HTML markup, normalization can be completely skipped because the // generated render function is guaranteed to return Array . There are // two cases where extra normalization is needed: // 1. When the children contains components - because a functional component // may return an Array instead of a single root. In this case, just a simple // normalization is needed - if any child is an Array, we flatten the whole // thing with Array.prototype.concat. It is guaranteed to be only 1-level deep // because functional components already normalize their own children. function simpleNormalizeChildren (children) { for (let i = 0; i < children.length; i++) { if (Array.isArray(children[i])) { return Array.prototype.concat.apply([], children) } } return children } // 2. When the children contains constructs that always generated nested Arrays, // e.g. , , v-for, or when the children is provided by user // with hand-written render functions / JSX. In such cases a full normalization // is needed to cater to all possible types of children values. function normalizeChildren (children) { return isPrimitive(children) ? [createTextVNode(children)] : Array.isArray(children) ? normalizeArrayChildren(children) : undefined } function isTextNode (node) { return isDef(node) && isDef(node.text) && isFalse(node.isComment) } function normalizeArrayChildren (children, nestedIndex) { const res = []; let i, c, lastIndex, last; for (i = 0; i < children.length; i++) { c = children[i]; if (isUndef(c) || typeof c === 'boolean') continue lastIndex = res.length - 1; last = res[lastIndex]; // nested if (Array.isArray(c)) { if (c.length > 0) { c = normalizeArrayChildren(c, `${nestedIndex || ''}_${i}`); // merge adjacent text nodes if (isTextNode(c[0]) && isTextNode(last)) { res[lastIndex] = createTextVNode(last.text + (c[0]).text); c.shift(); } res.push.apply(res, c); } } else if (isPrimitive(c)) { if (isTextNode(last)) { // merge adjacent text nodes // this is necessary for SSR hydration because text nodes are // essentially merged when rendered to HTML strings res[lastIndex] = createTextVNode(last.text + c); } else if (c !== '') { // convert primitive to vnode res.push(createTextVNode(c)); } } else { if (isTextNode(c) && isTextNode(last)) { // merge adjacent text nodes res[lastIndex] = createTextVNode(last.text + c.text); } else { // default key for nested array children (likely generated by v-for) if (isTrue(children._isVList) && isDef(c.tag) && isUndef(c.key) && isDef(nestedIndex)) { c.key = `__vlist${nestedIndex}_${i}__`; } res.push(c); } } } return res } /* */ function ensureCtor (comp, base) { if ( comp.__esModule || (hasSymbol && comp[Symbol.toStringTag] === 'Module') ) { comp = comp.default; } return isObject(comp) ? base.extend(comp) : comp } function createAsyncPlaceholder ( factory, data, context, children, tag ) { const node = createEmptyVNode(); node.asyncFactory = factory; node.asyncMeta = { data, context, children, tag }; return node } function resolveAsyncComponent ( factory, baseCtor, context ) { if (isTrue(factory.error) && isDef(factory.errorComp)) { return factory.errorComp } if (isDef(factory.resolved)) { return factory.resolved } if (isTrue(factory.loading) && isDef(factory.loadingComp)) { return factory.loadingComp } if (isDef(factory.contexts)) { // already pending factory.contexts.push(context); } else { const contexts = factory.contexts = [context]; let sync = true; const forceRender = (renderCompleted) => { for (let i = 0, l = contexts.length; i < l; i++) { contexts[i].$forceUpdate(); } if (renderCompleted) { contexts.length = 0; } }; const resolve = once((res) => { // cache resolved factory.resolved = ensureCtor(res, baseCtor); // invoke callbacks only if this is not a synchronous resolve // (async resolves are shimmed as synchronous during SSR) if (!sync) { forceRender(true); } else { contexts.length = 0; } }); const reject = once(reason => { warn( `Failed to resolve async component: ${String(factory)}` + (reason ? `\nReason: ${reason}` : '') ); if (isDef(factory.errorComp)) { factory.error = true; forceRender(true); } }); const res = factory(resolve, reject); if (isObject(res)) { if (isPromise(res)) { // () => Promise if (isUndef(factory.resolved)) { res.then(resolve, reject); } } else if (isPromise(res.component)) { res.component.then(resolve, reject); if (isDef(res.error)) { factory.errorComp = ensureCtor(res.error, baseCtor); } if (isDef(res.loading)) { factory.loadingComp = ensureCtor(res.loading, baseCtor); if (res.delay === 0) { factory.loading = true; } else { setTimeout(() => { if (isUndef(factory.resolved) && isUndef(factory.error)) { factory.loading = true; forceRender(false); } }, res.delay || 200); } } if (isDef(res.timeout)) { setTimeout(() => { if (isUndef(factory.resolved)) { reject( `timeout (${res.timeout}ms)` ); } }, res.timeout); } } } sync = false; // return in case resolved synchronously return factory.loading ? factory.loadingComp : factory.resolved } } /* */ function isAsyncPlaceholder (node) { return node.isComment && node.asyncFactory } /* */ function getFirstComponentChild (children) { if (Array.isArray(children)) { for (let i = 0; i < children.length; i++) { const c = children[i]; if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) { return c } } } } /* */ /* */ function initEvents (vm) { vm._events = Object.create(null); vm._hasHookEvent = false; // init parent attached events const listeners = vm.$options._parentListeners; if (listeners) { updateComponentListeners(vm, listeners); } } let target; function add (event, fn) { target.$on(event, fn); } function remove$1 (event, fn) { target.$off(event, fn); } function createOnceHandler (event, fn) { const _target = target; return function onceHandler () { const res = fn.apply(null, arguments); if (res !== null) { _target.$off(event, onceHandler); } } } function updateComponentListeners ( vm, listeners, oldListeners ) { target = vm; updateListeners(listeners, oldListeners || {}, add, remove$1, createOnceHandler, vm); target = undefined; } function eventsMixin (Vue) { const hookRE = /^hook:/; Vue.prototype.$on = function (event, fn) { const vm = this; if (Array.isArray(event)) { for (let i = 0, l = event.length; i < l; i++) { vm.$on(event[i], fn); } } else { (vm._events[event] || (vm._events[event] = [])).push(fn); // optimize hook:event cost by using a boolean flag marked at registration // instead of a hash lookup if (hookRE.test(event)) { vm._hasHookEvent = true; } } return vm }; Vue.prototype.$once = function (event, fn) { const 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) { const vm = this; // all if (!arguments.length) { vm._events = Object.create(null); return vm } // array of events if (Array.isArray(event)) { for (let i = 0, l = event.length; i < l; i++) { vm.$off(event[i], fn); } return vm } // specific event const cbs = vm._events[event]; if (!cbs) { return vm } if (!fn) { vm._events[event] = null; return vm } // specific handler let cb; let 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) { const vm = this; { const lowerCaseEvent = event.toLowerCase(); if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) { tip( `Event "${lowerCaseEvent}" is emitted in component ` + `${formatComponentName(vm)} but the handler is registered for "${event}". ` + `Note that HTML attributes are case-insensitive and you cannot use ` + `v-on to listen to camelCase events when using in-DOM templates. ` + `You should probably use "${hyphenate(event)}" instead of "${event}".` ); } } let cbs = vm._events[event]; if (cbs) { cbs = cbs.length > 1 ? toArray(cbs) : cbs; const args = toArray(arguments, 1); const info = `event handler for "${event}"`; for (let i = 0, l = cbs.length; i < l; i++) { invokeWithErrorHandling(cbs[i], vm, args, vm, info); } } return vm }; } /* */ /** * Runtime helper for resolving raw children VNodes into a slot object. */ function resolveSlots ( children, context ) { if (!children || !children.length) { return {} } const slots = {}; for (let i = 0, l = children.length; i < l; i++) { const child = children[i]; const data = child.data; // remove slot attribute if the node is resolved as a Vue slot node if (data && data.attrs && data.attrs.slot) { delete data.attrs.slot; } // named slots should only be respected if the vnode was rendered in the // same context. if ((child.context === context || child.fnContext === context) && data && data.slot != null ) { const name = data.slot; const slot = (slots[name] || (slots[name] = [])); if (child.tag === 'template') { slot.push.apply(slot, child.children || []); } else { slot.push(child); } } else { (slots.default || (slots.default = [])).push(child); } } // ignore slots that contains only whitespace for (const name in slots) { if (slots[name].every(isWhitespace)) { delete slots[name]; } } return slots } function isWhitespace (node) { return (node.isComment && !node.asyncFactory) || node.text === ' ' } function resolveScopedSlots ( fns, // see flow/vnode hasDynamicKeys, res ) { res = res || { $stable: !hasDynamicKeys }; for (let i = 0; i < fns.length; i++) { const slot = fns[i]; if (Array.isArray(slot)) { resolveScopedSlots(slot, hasDynamicKeys, res); } else if (slot) { res[slot.key] = slot.fn; } } return res } /* */ let activeInstance = null; let isUpdatingChildComponent = false; function setActiveInstance(vm) { const prevActiveInstance = activeInstance; activeInstance = vm; return () => { activeInstance = prevActiveInstance; } } function initLifecycle (vm) { const options = vm.$options; // locate first non-abstract parent let 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 = null; vm._directInactive = false; vm._isMounted = false; vm._isDestroyed = false; vm._isBeingDestroyed = false; } function lifecycleMixin (Vue) { Vue.prototype._update = function (vnode, hydrating) { const vm = this; const prevEl = vm.$el; const prevVnode = vm._vnode; const restoreActiveInstance = setActiveInstance(vm); vm._vnode = vnode; // Vue.prototype.__patch__ is injected in entry points // based on the rendering backend used. if (!prevVnode) { // initial render vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */); } else { // updates vm.$el = vm.__patch__(prevVnode, vnode); } restoreActiveInstance(); // 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; } // updated hook is called by the scheduler to ensure that children are // updated in a parent's updated hook. }; Vue.prototype.$forceUpdate = function () { const vm = this; if (vm._watcher) { vm._watcher.update(); } }; Vue.prototype.$destroy = function () { const vm = this; if (vm._isBeingDestroyed) { return } callHook(vm, 'beforeDestroy'); vm._isBeingDestroyed = true; // remove self from parent const parent = vm.$parent; if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) { remove(parent.$children, vm); } // teardown watchers if (vm._watcher) { vm._watcher.teardown(); } let 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; // invoke destroy hooks on current rendered tree vm.__patch__(vm._vnode, null); // fire destroyed hook callHook(vm, 'destroyed'); // turn off all instance listeners. vm.$off(); // remove __vue__ reference if (vm.$el) { vm.$el.__vue__ = null; } // release circular reference (#6759) if (vm.$vnode) { vm.$vnode.parent = null; } }; } function mountComponent ( vm, el, hydrating ) { vm.$el = el; if (!vm.$options.render) { vm.$options.render = createEmptyVNode; { /* istanbul ignore if */ if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') || vm.$options.el || el) { warn( 'You are using the runtime-only build of Vue where the template ' + 'compiler 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'); let updateComponent; /* istanbul ignore if */ if (config.performance && mark) { updateComponent = () => { const name = vm._name; const id = vm._uid; const startTag = `vue-perf-start:${id}`; const endTag = `vue-perf-end:${id}`; mark(startTag); const vnode = vm._render(); mark(endTag); measure(`vue ${name} render`, startTag, endTag); mark(startTag); vm._update(vnode, hydrating); mark(endTag); measure(`vue ${name} patch`, startTag, endTag); }; } else { updateComponent = () => { vm._update(vm._render(), hydrating); }; } // we set this to vm._watcher inside the watcher's constructor // since the watcher's initial patch may call $forceUpdate (e.g. inside child // component's mounted hook), which relies on vm._watcher being already defined new Watcher(vm, updateComponent, noop, { before () { if (vm._isMounted && !vm._isDestroyed) { callHook(vm, 'beforeUpdate'); } } }, true /* isRenderWatcher */); hydrating = false; // manually mounted instance, call mounted on self // mounted is called for render-created child components in its inserted hook if (vm.$vnode == null) { vm._isMounted = true; callHook(vm, 'mounted'); } return vm } function updateChildComponent ( vm, propsData, listeners, parentVnode, renderChildren ) { { isUpdatingChildComponent = true; } // determine whether component has slot children // we need to do this before overwriting $options._renderChildren. // check if there are dynamic scopedSlots (hand-written or compiled but with // dynamic slot names). Static scoped slots compiled from template has the // "$stable" marker. const hasDynamicScopedSlot = !!( (parentVnode.data.scopedSlots && !parentVnode.data.scopedSlots.$stable) || (vm.$scopedSlots !== emptyObject && !vm.$scopedSlots.$stable) ); // Any static slot children from the parent may have changed during parent's // update. Dynamic scoped slots may also have changed. In such cases, a forced // update is necessary to ensure correctness. const needsForceUpdate = !!( renderChildren || // has new static slots vm.$options._renderChildren || // has old static slots hasDynamicScopedSlot ); vm.$options._parentVnode = parentVnode; vm.$vnode = parentVnode; // update vm's placeholder node without re-render if (vm._vnode) { // update child tree's parent vm._vnode.parent = parentVnode; } vm.$options._renderChildren = renderChildren; // update $attrs and $listeners hash // these are also reactive so they may trigger child update if the child // used them during render vm.$attrs = parentVnode.data.attrs || emptyObject; vm.$listeners = listeners || emptyObject; // update props if (propsData && vm.$options.props) { toggleObserving(false); const props = vm._props; const propKeys = vm.$options._propKeys || []; for (let i = 0; i < propKeys.length; i++) { const key = propKeys[i]; const propOptions = vm.$options.props; // wtf flow? props[key] = validateProp(key, propOptions, propsData, vm); } toggleObserving(true); // keep a copy of raw propsData vm.$options.propsData = propsData; } // update listeners listeners = listeners || emptyObject; const oldListeners = vm.$options._parentListeners; vm.$options._parentListeners = listeners; updateComponentListeners(vm, listeners, oldListeners); // resolve slots + force update if has children if (needsForceUpdate) { vm.$slots = resolveSlots(renderChildren, parentVnode.context); vm.$forceUpdate(); } { isUpdatingChildComponent = false; } } function isInInactiveTree (vm) { while (vm && (vm = vm.$parent)) { if (vm._inactive) return true } return false } function activateChildComponent (vm, direct) { if (direct) { vm._directInactive = false; if (isInInactiveTree(vm)) { return } } else if (vm._directInactive) { return } if (vm._inactive || vm._inactive === null) { vm._inactive = false; for (let i = 0; i < vm.$children.length; i++) { activateChildComponent(vm.$children[i]); } callHook(vm, 'activated'); } } function deactivateChildComponent (vm, direct) { if (direct) { vm._directInactive = true; if (isInInactiveTree(vm)) { return } } if (!vm._inactive) { vm._inactive = true; for (let i = 0; i < vm.$children.length; i++) { deactivateChildComponent(vm.$children[i]); } callHook(vm, 'deactivated'); } } function callHook (vm, hook) { // #7573 disable dep collection when invoking lifecycle hooks pushTarget(); const handlers = vm.$options[hook]; const info = `${hook} hook`; if (handlers) { for (let i = 0, j = handlers.length; i < j; i++) { invokeWithErrorHandling(handlers[i], vm, null, vm, info); } } if (vm._hasHookEvent) { vm.$emit('hook:' + hook); } popTarget(); } /* */ const MAX_UPDATE_COUNT = 100; const queue = []; const activatedChildren = []; let has = {}; let circular = {}; let waiting = false; let flushing = false; let index = 0; /** * Reset the scheduler's state. */ function resetSchedulerState () { index = queue.length = activatedChildren.length = 0; has = {}; { circular = {}; } waiting = flushing = false; } // Async edge case #6566 requires saving the timestamp when event listeners are // attached. However, calling performance.now() has a perf overhead especially // if the page has thousands of event listeners. Instead, we take a timestamp // every time the scheduler flushes and use that for all event listeners // attached during that flush. let currentFlushTimestamp = 0; // Async edge case fix requires storing an event listener's attach timestamp. let getNow = Date.now; // Determine what event timestamp the browser is using. Annoyingly, the // timestamp can either be hi-res ( relative to poge load) or low-res // (relative to UNIX epoch), so in order to compare time we have to use the // same timestamp type when saving the flush timestamp. if (inBrowser && getNow() > document.createEvent('Event').timeStamp) { // if the low-res timestamp which is bigger than the event timestamp // (which is evaluated AFTER) it means the event is using a hi-res timestamp, // and we need to use the hi-res version for event listeners as well. getNow = () => performance.now(); } /** * Flush both queues and run the watchers. */ function flushSchedulerQueue () { currentFlushTimestamp = getNow(); flushing = true; let watcher, id; // 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((a, b) => 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++) { watcher = queue[index]; if (watcher.before) { watcher.before(); } id = watcher.id; has[id] = null; watcher.run(); // in dev build, check and stop circular updates. if (has[id] != null) { circular[id] = (circular[id] || 0) + 1; if (circular[id] > MAX_UPDATE_COUNT) { warn( 'You may have an infinite update loop ' + ( watcher.user ? `in watcher with expression "${watcher.expression}"` : `in a component render function.` ), watcher.vm ); break } } } // keep copies of post queues before resetting state const activatedQueue = activatedChildren.slice(); const updatedQueue = queue.slice(); resetSchedulerState(); // call component updated and activated hooks callActivatedHooks(activatedQueue); callUpdatedHooks(updatedQueue); // devtool hook /* istanbul ignore if */ if (devtools && config.devtools) { devtools.emit('flush'); } } function callUpdatedHooks (queue) { let i = queue.length; while (i--) { const watcher = queue[i]; const vm = watcher.vm; if (vm._watcher === watcher && vm._isMounted && !vm._isDestroyed) { callHook(vm, 'updated'); } } } /** * Queue a kept-alive component that was activated during patch. * The queue will be processed after the entire tree has been patched. */ function queueActivatedComponent (vm) { // setting _inactive to false here so that a render function can // rely on checking whether it's in an inactive tree (e.g. router-view) vm._inactive = false; activatedChildren.push(vm); } function callActivatedHooks (queue) { for (let i = 0; i < queue.length; i++) { queue[i]._inactive = true; activateChildComponent(queue[i], true /* true */); } } /** * 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) { const 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. let i = queue.length - 1; while (i > index && queue[i].id > watcher.id) { i--; } queue.splice(i + 1, 0, watcher); } // queue the flush if (!waiting) { waiting = true; if (!config.async) { flushSchedulerQueue(); return } nextTick(flushSchedulerQueue); } } } /* */ let 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. */ class Watcher { constructor ( vm, expOrFn, cb, options, isRenderWatcher ) { this.vm = vm; if (isRenderWatcher) { vm._watcher = this; } vm._watchers.push(this); // options if (options) { this.deep = !!options.deep; this.user = !!options.user; this.lazy = !!options.lazy; this.sync = !!options.sync; this.before = options.before; } else { this.deep = this.user = this.lazy = this.sync = false; } 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(); this.expression = expOrFn.toString(); // parse expression for getter if (typeof expOrFn === 'function') { this.getter = expOrFn; } else { this.getter = parsePath(expOrFn); if (!this.getter) { this.getter = noop; 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. */ get () { pushTarget(this); let value; const vm = this.vm; try { value = this.getter.call(vm, vm); } catch (e) { if (this.user) { handleError(e, vm, `getter for watcher "${this.expression}"`); } else { throw e } } finally { // "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. */ addDep (dep) { const 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. */ cleanupDeps () { let i = this.deps.length; while (i--) { const dep = this.deps[i]; if (!this.newDepIds.has(dep.id)) { dep.removeSub(this); } } let 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. */ 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. */ run () { if (this.active) { const 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 const oldValue = this.value; this.value = value; if (this.user) { try { this.cb.call(this.vm, value, oldValue); } catch (e) { handleError(e, this.vm, `callback for watcher "${this.expression}"`); } } else { this.cb.call(this.vm, value, oldValue); } } } } /** * Evaluate the value of the watcher. * This only gets called for lazy watchers. */ evaluate () { this.value = this.get(); this.dirty = false; } /** * Depend on all deps collected by this watcher. */ depend () { let i = this.deps.length; while (i--) { this.deps[i].depend(); } } /** * Remove self from all dependencies' subscriber list. */ teardown () { 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. if (!this.vm._isBeingDestroyed) { remove(this.vm._watchers, this); } let i = this.deps.length; while (i--) { this.deps[i].removeSub(this); } this.active = false; } } } /* */ const sharedPropertyDefinition = { enumerable: true, configurable: true, get: noop, set: noop }; function proxy (target, sourceKey, key) { sharedPropertyDefinition.get = function proxyGetter () { return this[sourceKey][key] }; sharedPropertyDefinition.set = function proxySetter (val) { this[sourceKey][key] = val; }; Object.defineProperty(target, key, sharedPropertyDefinition); } function initState (vm) { vm._watchers = []; const opts = vm.$options; if (opts.props) initProps(vm, opts.props); if (opts.methods) initMethods(vm, opts.methods); if (opts.data) { initData(vm); } else { observe(vm._data = {}, true /* asRootData */); } if (opts.computed) initComputed(vm, opts.computed); if (opts.watch && opts.watch !== nativeWatch) { initWatch(vm, opts.watch); } } function initProps (vm, propsOptions) { const propsData = vm.$options.propsData || {}; const props = vm._props = {}; // cache prop keys so that future props updates can iterate using Array // instead of dynamic object key enumeration. const keys = vm.$options._propKeys = []; const isRoot = !vm.$parent; // root instance props should be converted if (!isRoot) { toggleObserving(false); } for (const key in propsOptions) { keys.push(key); const value = validateProp(key, propsOptions, propsData, vm); /* istanbul ignore else */ { const hyphenatedKey = hyphenate(key); if (isReservedAttribute(hyphenatedKey) || config.isReservedAttr(hyphenatedKey)) { warn( `"${hyphenatedKey}" is a reserved attribute and cannot be used as component prop.`, vm ); } defineReactive$$1(props, key, value, () => { if (!isRoot && !isUpdatingChildComponent) { 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 ); } }); } // static props are already proxied on the component's prototype // during Vue.extend(). We only need to proxy props defined at // instantiation here. if (!(key in vm)) { proxy(vm, `_props`, key); } } toggleObserving(true); } function initData (vm) { let data = vm.$options.data; data = vm._data = typeof data === 'function' ? getData(data, vm) : data || {}; if (!isPlainObject(data)) { data = {}; warn( 'data functions should return an object:\n' + 'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function', vm ); } // proxy data on instance const keys = Object.keys(data); const props = vm.$options.props; const methods = vm.$options.methods; let i = keys.length; while (i--) { const key = keys[i]; { if (methods && hasOwn(methods, key)) { warn( `Method "${key}" has already been defined as a data property.`, vm ); } } if (props && hasOwn(props, key)) { warn( `The data property "${key}" is already declared as a prop. ` + `Use prop default value instead.`, vm ); } else if (!isReserved(key)) { proxy(vm, `_data`, key); } } // observe data observe(data, true /* asRootData */); } function getData (data, vm) { // #7573 disable dep collection when invoking data getters pushTarget(); try { return data.call(vm, vm) } catch (e) { handleError(e, vm, `data()`); return {} } finally { popTarget(); } } const computedWatcherOptions = { lazy: true }; function initComputed (vm, computed) { // $flow-disable-line const watchers = vm._computedWatchers = Object.create(null); // computed properties are just getters during SSR const isSSR = isServerRendering(); for (const key in computed) { const userDef = computed[key]; const getter = typeof userDef === 'function' ? userDef : userDef.get; if (getter == null) { warn( `Getter is missing for computed property "${key}".`, vm ); } if (!isSSR) { // create internal watcher for the computed property. watchers[key] = new Watcher( vm, getter || noop, noop, computedWatcherOptions ); } // component-defined computed properties are already defined on the // component prototype. We only need to define computed properties defined // at instantiation here. if (!(key in vm)) { defineComputed(vm, key, userDef); } else { if (key in vm.$data) { warn(`The computed property "${key}" is already defined in data.`, vm); } else if (vm.$options.props && key in vm.$options.props) { warn(`The computed property "${key}" is already defined as a prop.`, vm); } } } } function defineComputed ( target, key, userDef ) { const shouldCache = !isServerRendering(); if (typeof userDef === 'function') { sharedPropertyDefinition.get = shouldCache ? createComputedGetter(key) : createGetterInvoker(userDef); sharedPropertyDefinition.set = noop; } else { sharedPropertyDefinition.get = userDef.get ? shouldCache && userDef.cache !== false ? createComputedGetter(key) : createGetterInvoker(userDef.get) : noop; sharedPropertyDefinition.set = userDef.set || noop; } if (sharedPropertyDefinition.set === noop) { sharedPropertyDefinition.set = function () { warn( `Computed property "${key}" was assigned to but it has no setter.`, this ); }; } Object.defineProperty(target, key, sharedPropertyDefinition); } function createComputedGetter (key) { return function computedGetter () { const watcher = this._computedWatchers && this._computedWatchers[key]; if (watcher) { if (watcher.dirty) { watcher.evaluate(); } if (Dep.target) { watcher.depend(); } return watcher.value } } } function createGetterInvoker(fn) { return function computedGetter () { return fn.call(this, this) } } function initMethods (vm, methods) { const props = vm.$options.props; for (const key in methods) { { if (typeof methods[key] !== 'function') { warn( `Method "${key}" has type "${typeof methods[key]}" in the component definition. ` + `Did you reference the function correctly?`, vm ); } if (props && hasOwn(props, key)) { warn( `Method "${key}" has already been defined as a prop.`, vm ); } if ((key in vm) && isReserved(key)) { warn( `Method "${key}" conflicts with an existing Vue instance method. ` + `Avoid defining component methods that start with _ or $.` ); } } vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm); } } function initWatch (vm, watch) { for (const key in watch) { const handler = watch[key]; if (Array.isArray(handler)) { for (let i = 0; i < handler.length; i++) { createWatcher(vm, key, handler[i]); } } else { createWatcher(vm, key, handler); } } } function createWatcher ( vm, expOrFn, handler, options ) { if (isPlainObject(handler)) { options = handler; handler = handler.handler; } if (typeof handler === 'string') { handler = vm[handler]; } return vm.$watch(expOrFn, 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. const dataDef = {}; dataDef.get = function () { return this._data }; const propsDef = {}; propsDef.get = function () { return this._props }; { dataDef.set = function () { warn( 'Avoid replacing instance root $data. ' + 'Use nested data properties instead.', this ); }; propsDef.set = function () { warn(`$props is readonly.`, this); }; } Object.defineProperty(Vue.prototype, '$data', dataDef); Object.defineProperty(Vue.prototype, '$props', propsDef); Vue.prototype.$set = set; Vue.prototype.$delete = del; Vue.prototype.$watch = function ( expOrFn, cb, options ) { const vm = this; if (isPlainObject(cb)) { return createWatcher(vm, expOrFn, cb, options) } options = options || {}; options.user = true; const watcher = new Watcher(vm, expOrFn, cb, options); if (options.immediate) { try { cb.call(vm, watcher.value); } catch (error) { handleError(error, vm, `callback for immediate watcher "${watcher.expression}"`); } } return function unwatchFn () { watcher.teardown(); } }; } /* */ function initProvide (vm) { const provide = vm.$options.provide; if (provide) { vm._provided = typeof provide === 'function' ? provide.call(vm) : provide; } } function initInjections (vm) { const result = resolveInject(vm.$options.inject, vm); if (result) { toggleObserving(false); Object.keys(result).forEach(key => { /* istanbul ignore else */ { defineReactive$$1(vm, key, result[key], () => { warn( `Avoid mutating an injected value directly since the changes will be ` + `overwritten whenever the provided component re-renders. ` + `injection being mutated: "${key}"`, vm ); }); } }); toggleObserving(true); } } function resolveInject (inject, vm) { if (inject) { // inject is :any because flow is not smart enough to figure out cached const result = Object.create(null); const keys = hasSymbol ? Reflect.ownKeys(inject) : Object.keys(inject); for (let i = 0; i < keys.length; i++) { const key = keys[i]; // #6574 in case the inject object is observed... if (key === '__ob__') continue const provideKey = inject[key].from; let source = vm; while (source) { if (source._provided && hasOwn(source._provided, provideKey)) { result[key] = source._provided[provideKey]; break } source = source.$parent; } if (!source) { if ('default' in inject[key]) { const provideDefault = inject[key].default; result[key] = typeof provideDefault === 'function' ? provideDefault.call(vm) : provideDefault; } else { warn(`Injection "${key}" not found`, vm); } } } return result } } /* */ function normalizeScopedSlots ( slots, normalSlots ) { let res; if (!slots) { res = {}; } else if (slots._normalized) { return slots } else { res = {}; for (const key in slots) { if (slots[key] && key[0] !== '$') { res[key] = normalizeScopedSlot(slots[key]); } } } // expose normal slots on scopedSlots for (const key in normalSlots) { if (!(key in res)) { res[key] = proxyNormalSlot(normalSlots, key); } } res._normalized = true; res.$stable = slots ? slots.$stable : true; return res } function normalizeScopedSlot(fn) { return scope => { const res = fn(scope); return res && typeof res === 'object' && !Array.isArray(res) ? [res] // single vnode : normalizeChildren(res) } } function proxyNormalSlot(slots, key) { return () => slots[key] } /* */ /** * Runtime helper for rendering v-for lists. */ function renderList ( val, render ) { let ret, i, l, keys, key; if (Array.isArray(val) || typeof val === 'string') { 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)) { if (hasSymbol && val[Symbol.iterator]) { ret = []; const iterator = val[Symbol.iterator](); let result = iterator.next(); while (!result.done) { ret.push(render(result.value, ret.length)); result = iterator.next(); } } else { 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); } } } if (!isDef(ret)) { ret = []; } (ret)._isVList = true; return ret } /* */ /** * Runtime helper for rendering */ function renderSlot ( name, fallback, props, bindObject ) { const scopedSlotFn = this.$scopedSlots[name]; let nodes; if (scopedSlotFn) { // scoped slot props = props || {}; if (bindObject) { if (!isObject(bindObject)) { warn( 'slot v-bind without argument expects an Object', this ); } props = extend(extend({}, bindObject), props); } nodes = scopedSlotFn(props) || fallback; } else { nodes = this.$slots[name] || fallback; } const target = props && props.slot; if (target) { return this.$createElement('template', { slot: target }, nodes) } else { return nodes } } /* */ /** * Runtime helper for resolving filters */ function resolveFilter (id) { return resolveAsset(this.$options, 'filters', id, true) || identity } /* */ function isKeyNotMatch (expect, actual) { if (Array.isArray(expect)) { return expect.indexOf(actual) === -1 } else { return expect !== actual } } /** * Runtime helper for checking keyCodes from config. * exposed as Vue.prototype._k * passing in eventKeyName as last argument separately for backwards compat */ function checkKeyCodes ( eventKeyCode, key, builtInKeyCode, eventKeyName, builtInKeyName ) { const mappedKeyCode = config.keyCodes[key] || builtInKeyCode; if (builtInKeyName && eventKeyName && !config.keyCodes[key]) { return isKeyNotMatch(builtInKeyName, eventKeyName) } else if (mappedKeyCode) { return isKeyNotMatch(mappedKeyCode, eventKeyCode) } else if (eventKeyName) { return hyphenate(eventKeyName) !== key } } /* */ /** * Runtime helper for merging v-bind="object" into a VNode's data. */ function bindObjectProps ( data, tag, value, asProp, isSync ) { if (value) { if (!isObject(value)) { warn( 'v-bind without argument expects an Object or Array value', this ); } else { if (Array.isArray(value)) { value = toObject(value); } let hash; for (const key in value) { if ( key === 'class' || key === 'style' || isReservedAttribute(key) ) { hash = data; } else { const type = data.attrs && data.attrs.type; hash = asProp || config.mustUseProp(tag, type, key) ? data.domProps || (data.domProps = {}) : data.attrs || (data.attrs = {}); } const camelizedKey = camelize(key); if (!(key in hash) && !(camelizedKey in hash)) { hash[key] = value[key]; if (isSync) { const on = data.on || (data.on = {}); on[`update:${camelizedKey}`] = function ($event) { value[key] = $event; }; } } } } } return data } /* */ /** * Runtime helper for rendering static trees. */ function renderStatic ( index, isInFor ) { const cached = this._staticTrees || (this._staticTrees = []); let tree = cached[index]; // if has already-rendered static tree and not inside v-for, // we can reuse the same tree. if (tree && !isInFor) { return tree } // otherwise, render a fresh tree. tree = cached[index] = this.$options.staticRenderFns[index].call( this._renderProxy, null, this // for render fns generated for functional component templates ); markStatic(tree, `__static__${index}`, false); return tree } /** * Runtime helper for v-once. * Effectively it means marking the node as static with a unique key. */ function markOnce ( tree, index, key ) { markStatic(tree, `__once__${index}${key ? `_${key}` : ``}`, true); return tree } function markStatic ( tree, key, isOnce ) { if (Array.isArray(tree)) { for (let i = 0; i < tree.length; i++) { if (tree[i] && typeof tree[i] !== 'string') { markStaticNode(tree[i], `${key}_${i}`, isOnce); } } } else { markStaticNode(tree, key, isOnce); } } function markStaticNode (node, key, isOnce) { node.isStatic = true; node.key = key; node.isOnce = isOnce; } /* */ function bindObjectListeners (data, value) { if (value) { if (!isPlainObject(value)) { warn( 'v-on without argument expects an Object value', this ); } else { const on = data.on = data.on ? extend({}, data.on) : {}; for (const key in value) { const existing = on[key]; const ours = value[key]; on[key] = existing ? [].concat(existing, ours) : ours; } } } return data } /* */ function bindDynamicKeys (baseObj, values) { for (let i = 0; i < values.length; i += 2) { const key = values[i]; if (typeof key === 'string' && key) { baseObj[values[i]] = values[i + 1]; } else if (key !== '' && key !== null) { // null is a speical value for explicitly removing a binding warn( `Invalid value for dynamic directive argument (expected string or null): ${key}`, this ); } } return baseObj } // helper to dynamically append modifier runtime markers to event names. // ensure only append when value is already string, otherwise it will be cast // to string and cause the type check to miss. function prependModifier (value, symbol) { return typeof value === 'string' ? symbol + value : value } /* */ function installRenderHelpers (target) { target._o = markOnce; target._n = toNumber; target._s = toString; target._l = renderList; target._t = renderSlot; target._q = looseEqual; target._i = looseIndexOf; target._m = renderStatic; target._f = resolveFilter; target._k = checkKeyCodes; target._b = bindObjectProps; target._v = createTextVNode; target._e = createEmptyVNode; target._u = resolveScopedSlots; target._g = bindObjectListeners; target._d = bindDynamicKeys; target._p = prependModifier; } /* */ function FunctionalRenderContext ( data, props, children, parent, Ctor ) { const options = Ctor.options; // ensure the createElement function in functional components // gets a unique context - this is necessary for correct named slot check let contextVm; if (hasOwn(parent, '_uid')) { contextVm = Object.create(parent); // $flow-disable-line contextVm._original = parent; } else { // the context vm passed in is a functional context as well. // in this case we want to make sure we are able to get a hold to the // real context instance. contextVm = parent; // $flow-disable-line parent = parent._original; } const isCompiled = isTrue(options._compiled); const needNormalization = !isCompiled; this.data = data; this.props = props; this.children = children; this.parent = parent; this.listeners = data.on || emptyObject; this.injections = resolveInject(options.inject, parent); this.slots = () => resolveSlots(children, parent); Object.defineProperty(this, 'scopedSlots', ({ enumerable: true, get () { return normalizeScopedSlots(data.scopedSlots, this.slots()) } })); // support for compiled functional template if (isCompiled) { // exposing $options for renderStatic() this.$options = options; // pre-resolve slots for renderSlot() this.$slots = this.slots(); this.$scopedSlots = normalizeScopedSlots(data.scopedSlots, this.$slots); } if (options._scopeId) { this._c = (a, b, c, d) => { const vnode = createElement(contextVm, a, b, c, d, needNormalization); if (vnode && !Array.isArray(vnode)) { vnode.fnScopeId = options._scopeId; vnode.fnContext = parent; } return vnode }; } else { this._c = (a, b, c, d) => createElement(contextVm, a, b, c, d, needNormalization); } } installRenderHelpers(FunctionalRenderContext.prototype); function createFunctionalComponent ( Ctor, propsData, data, contextVm, children ) { const options = Ctor.options; const props = {}; const propOptions = options.props; if (isDef(propOptions)) { for (const key in propOptions) { props[key] = validateProp(key, propOptions, propsData || emptyObject); } } else { if (isDef(data.attrs)) mergeProps(props, data.attrs); if (isDef(data.props)) mergeProps(props, data.props); } const renderContext = new FunctionalRenderContext( data, props, children, contextVm, Ctor ); const vnode = options.render.call(null, renderContext._c, renderContext); if (vnode instanceof VNode) { return cloneAndMarkFunctionalResult(vnode, data, renderContext.parent, options, renderContext) } else if (Array.isArray(vnode)) { const vnodes = normalizeChildren(vnode) || []; const res = new Array(vnodes.length); for (let i = 0; i < vnodes.length; i++) { res[i] = cloneAndMarkFunctionalResult(vnodes[i], data, renderContext.parent, options, renderContext); } return res } } function cloneAndMarkFunctionalResult (vnode, data, contextVm, options, renderContext) { // #7817 clone node before setting fnContext, otherwise if the node is reused // (e.g. it was from a cached normal slot) the fnContext causes named slots // that should not be matched to match. const clone = cloneVNode(vnode); clone.fnContext = contextVm; clone.fnOptions = options; { (clone.devtoolsMeta = clone.devtoolsMeta || {}).renderContext = renderContext; } if (data.slot) { (clone.data || (clone.data = {})).slot = data.slot; } return clone } function mergeProps (to, from) { for (const key in from) { to[camelize(key)] = from[key]; } } /* */ /* */ /* */ /* */ // inline hooks to be invoked on component VNodes during patch const componentVNodeHooks = { init (vnode, hydrating) { if ( vnode.componentInstance && !vnode.componentInstance._isDestroyed && vnode.data.keepAlive ) { // kept-alive components, treat as a patch const mountedNode = vnode; // work around flow componentVNodeHooks.prepatch(mountedNode, mountedNode); } else { const child = vnode.componentInstance = createComponentInstanceForVnode( vnode, activeInstance ); child.$mount(hydrating ? vnode.elm : undefined, hydrating); } }, prepatch (oldVnode, vnode) { const options = vnode.componentOptions; const child = vnode.componentInstance = oldVnode.componentInstance; updateChildComponent( child, options.propsData, // updated props options.listeners, // updated listeners vnode, // new parent vnode options.children // new children ); }, insert (vnode) { const { context, componentInstance } = vnode; if (!componentInstance._isMounted) { componentInstance._isMounted = true; callHook(componentInstance, 'mounted'); } if (vnode.data.keepAlive) { if (context._isMounted) { // vue-router#1212 // During updates, a kept-alive component's child components may // change, so directly walking the tree here may call activated hooks // on incorrect children. Instead we push them into a queue which will // be processed after the whole patch process ended. queueActivatedComponent(componentInstance); } else { activateChildComponent(componentInstance, true /* direct */); } } }, destroy (vnode) { const { componentInstance } = vnode; if (!componentInstance._isDestroyed) { if (!vnode.data.keepAlive) { componentInstance.$destroy(); } else { deactivateChildComponent(componentInstance, true /* direct */); } } } }; const hooksToMerge = Object.keys(componentVNodeHooks); function createComponent ( Ctor, data, context, children, tag ) { if (isUndef(Ctor)) { return } const baseCtor = context.$options._base; // plain options object: turn it into a constructor if (isObject(Ctor)) { Ctor = baseCtor.extend(Ctor); } // if at this stage it's not a constructor or an async component factory, // reject. if (typeof Ctor !== 'function') { { warn(`Invalid Component definition: ${String(Ctor)}`, context); } return } // async component let asyncFactory; if (isUndef(Ctor.cid)) { asyncFactory = Ctor; Ctor = resolveAsyncComponent(asyncFactory, baseCtor, context); if (Ctor === undefined) { // return a placeholder node for async component, which is rendered // as a comment node but preserves all the raw information for the node. // the information will be used for async server-rendering and hydration. return createAsyncPlaceholder( asyncFactory, data, context, children, tag ) } } data = data || {}; // resolve constructor options in case global mixins are applied after // component constructor creation resolveConstructorOptions(Ctor); // transform component v-model data into props & events if (isDef(data.model)) { transformModel(Ctor.options, data); } // extract props const propsData = extractPropsFromVNodeData(data, Ctor, tag); // functional component if (isTrue(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 const listeners = data.on; // replace with listeners with .native modifier // so it gets processed during parent component patch. data.on = data.nativeOn; if (isTrue(Ctor.options.abstract)) { // abstract components do not keep anything // other than props & listeners & slot // work around flow const slot = data.slot; data = {}; if (slot) { data.slot = slot; } } // install component management hooks onto the placeholder node installComponentHooks(data); // return a placeholder vnode const name = Ctor.options.name || tag; const vnode = new VNode( `vue-component-${Ctor.cid}${name ? `-${name}` : ''}`, data, undefined, undefined, undefined, context, { Ctor, propsData, listeners, tag, children }, asyncFactory ); return vnode } function createComponentInstanceForVnode ( vnode, // we know it's MountedComponentVNode but flow doesn't parent, // activeInstance in lifecycle state ) { const options = { _isComponent: true, _parentVnode: vnode, parent }; // check inline-template render functions const inlineTemplate = vnode.data.inlineTemplate; if (isDef(inlineTemplate)) { options.render = inlineTemplate.render; options.staticRenderFns = inlineTemplate.staticRenderFns; } return new vnode.componentOptions.Ctor(options) } function installComponentHooks (data) { const hooks = data.hook || (data.hook = {}); for (let i = 0; i < hooksToMerge.length; i++) { const key = hooksToMerge[i]; const existing = hooks[key]; const toMerge = componentVNodeHooks[key]; if (existing !== toMerge && !(existing && existing._merged)) { hooks[key] = existing ? mergeHook$1(toMerge, existing) : toMerge; } } } function mergeHook$1 (f1, f2) { const merged = (a, b) => { // flow complains about extra args which is why we use any f1(a, b); f2(a, b); }; merged._merged = true; return merged } // transform component v-model info (value and callback) into // prop and event handler respectively. function transformModel (options, data) { const prop = (options.model && options.model.prop) || 'value'; const event = (options.model && options.model.event) || 'input' ;(data.props || (data.props = {}))[prop] = data.model.value; const on = data.on || (data.on = {}); const existing = on[event]; const callback = data.model.callback; if (isDef(existing)) { if ( Array.isArray(existing) ? existing.indexOf(callback) === -1 : existing !== callback ) { on[event] = [callback].concat(existing); } } else { on[event] = callback; } } /* */ const SIMPLE_NORMALIZE = 1; const ALWAYS_NORMALIZE = 2; // wrapper function for providing a more flexible interface // without getting yelled at by flow function createElement ( context, tag, data, children, normalizationType, alwaysNormalize ) { if (Array.isArray(data) || isPrimitive(data)) { normalizationType = children; children = data; data = undefined; } if (isTrue(alwaysNormalize)) { normalizationType = ALWAYS_NORMALIZE; } return _createElement(context, tag, data, children, normalizationType) } function _createElement ( context, tag, data, children, normalizationType ) { if (isDef(data) && isDef((data).__ob__)) { warn( `Avoid using observed data object as vnode data: ${JSON.stringify(data)}\n` + 'Always create fresh vnode data objects in each render!', context ); return createEmptyVNode() } // object syntax in v-bind if (isDef(data) && isDef(data.is)) { tag = data.is; } if (!tag) { // in case of component :is set to falsy value return createEmptyVNode() } // warn against non-primitive key if (isDef(data) && isDef(data.key) && !isPrimitive(data.key) ) { { warn( 'Avoid using non-primitive value as key, ' + 'use string/number value instead.', context ); } } // support single function children as default scoped slot if (Array.isArray(children) && typeof children[0] === 'function' ) { data = data || {}; data.scopedSlots = { default: children[0] }; children.length = 0; } if (normalizationType === ALWAYS_NORMALIZE) { children = normalizeChildren(children); } else if (normalizationType === SIMPLE_NORMALIZE) { children = simpleNormalizeChildren(children); } let vnode, ns; if (typeof tag === 'string') { let Ctor; ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag); if (config.isReservedTag(tag)) { // platform built-in elements vnode = new VNode( config.parsePlatformTagName(tag), data, children, undefined, undefined, context ); } else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) { // component vnode = 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 vnode = new VNode( tag, data, children, undefined, undefined, context ); } } else { // direct component options / constructor vnode = createComponent(tag, data, context, children); } if (Array.isArray(vnode)) { return vnode } else if (isDef(vnode)) { if (isDef(ns)) applyNS(vnode, ns); if (isDef(data)) registerDeepBindings(data); return vnode } else { return createEmptyVNode() } } function applyNS (vnode, ns, force) { vnode.ns = ns; if (vnode.tag === 'foreignObject') { // use default namespace inside foreignObject ns = undefined; force = true; } if (isDef(vnode.children)) { for (let i = 0, l = vnode.children.length; i < l; i++) { const child = vnode.children[i]; if (isDef(child.tag) && ( isUndef(child.ns) || (isTrue(force) && child.tag !== 'svg'))) { applyNS(child, ns, force); } } } } // ref #5318 // necessary to ensure parent re-render when deep bindings like :style and // :class are used on slot nodes function registerDeepBindings (data) { if (isObject(data.style)) { traverse(data.style); } if (isObject(data.class)) { traverse(data.class); } } /* */ function initRender (vm) { vm._vnode = null; // the root of the child tree vm._staticTrees = null; // v-once cached trees const options = vm.$options; const parentVnode = vm.$vnode = options._parentVnode; // the placeholder node in parent tree const renderContext = parentVnode && parentVnode.context; vm.$slots = resolveSlots(options._renderChildren, renderContext); vm.$scopedSlots = emptyObject; // bind the createElement fn to this instance // so that we get proper render context inside it. // args order: tag, data, children, normalizationType, alwaysNormalize // internal version is used by render functions compiled from templates vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false); // normalization is always applied for the public version, used in // user-written render functions. vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true); // $attrs & $listeners are exposed for easier HOC creation. // they need to be reactive so that HOCs using them are always updated const parentData = parentVnode && parentVnode.data; /* istanbul ignore else */ { defineReactive$$1(vm, '$attrs', parentData && parentData.attrs || emptyObject, () => { !isUpdatingChildComponent && warn(`$attrs is readonly.`, vm); }, true); defineReactive$$1(vm, '$listeners', options._parentListeners || emptyObject, () => { !isUpdatingChildComponent && warn(`$listeners is readonly.`, vm); }, true); } } function renderMixin (Vue) { // install runtime convenience helpers installRenderHelpers(Vue.prototype); Vue.prototype.$nextTick = function (fn) { return nextTick(fn, this) }; Vue.prototype._render = function () { const vm = this; const { render, _parentVnode } = vm.$options; if (_parentVnode) { vm.$scopedSlots = normalizeScopedSlots( _parentVnode.data.scopedSlots, vm.$slots ); } // set parent vnode. this allows render functions to have access // to the data on the placeholder node. vm.$vnode = _parentVnode; // render self let vnode; try { vnode = render.call(vm._renderProxy, vm.$createElement); } catch (e) { handleError(e, vm, `render`); // return error render result, // or previous vnode to prevent render error causing blank component /* istanbul ignore else */ if (vm.$options.renderError) { try { vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e); } catch (e) { handleError(e, vm, `renderError`); vnode = vm._vnode; } } else { vnode = vm._vnode; } } // if the returned array contains only a single node, allow it if (Array.isArray(vnode) && vnode.length === 1) { vnode = vnode[0]; } // return empty vnode in case the render function errored out if (!(vnode instanceof VNode)) { if (Array.isArray(vnode)) { warn( 'Multiple root nodes returned from render function. Render function ' + 'should return a single root node.', vm ); } vnode = createEmptyVNode(); } // set parent vnode.parent = _parentVnode; return vnode }; } /* */ let uid$3 = 0; function initMixin (Vue) { Vue.prototype._init = function (options) { const vm = this; // a uid vm._uid = uid$3++; let startTag, endTag; /* istanbul ignore if */ if (config.performance && mark) { startTag = `vue-perf-start:${vm._uid}`; endTag = `vue-perf-end:${vm._uid}`; mark(startTag); } // 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.constructor), options || {}, vm ); } /* istanbul ignore else */ { initProxy(vm); } // expose real self vm._self = vm; initLifecycle(vm); initEvents(vm); initRender(vm); callHook(vm, 'beforeCreate'); initInjections(vm); // resolve injections before data/props initState(vm); initProvide(vm); // resolve provide after data/props callHook(vm, 'created'); /* istanbul ignore if */ if (config.performance && mark) { vm._name = formatComponentName(vm, false); mark(endTag); measure(`vue ${vm._name} init`, startTag, endTag); } if (vm.$options.el) { vm.$mount(vm.$options.el); } }; } function initInternalComponent (vm, options) { const opts = vm.$options = Object.create(vm.constructor.options); // doing this because it's faster than dynamic enumeration. const parentVnode = options._parentVnode; opts.parent = options.parent; opts._parentVnode = parentVnode; const vnodeComponentOptions = parentVnode.componentOptions; opts.propsData = vnodeComponentOptions.propsData; opts._parentListeners = vnodeComponentOptions.listeners; opts._renderChildren = vnodeComponentOptions.children; opts._componentTag = vnodeComponentOptions.tag; if (options.render) { opts.render = options.render; opts.staticRenderFns = options.staticRenderFns; } } function resolveConstructorOptions (Ctor) { let options = Ctor.options; if (Ctor.super) { const superOptions = resolveConstructorOptions(Ctor.super); const cachedSuperOptions = Ctor.superOptions; if (superOptions !== cachedSuperOptions) { // super option changed, // need to resolve new options. Ctor.superOptions = superOptions; // check if there are any late-modified/attached options (#4976) const modifiedOptions = resolveModifiedOptions(Ctor); // update base extend options if (modifiedOptions) { extend(Ctor.extendOptions, modifiedOptions); } options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions); if (options.name) { options.components[options.name] = Ctor; } } } return options } function resolveModifiedOptions (Ctor) { let modified; const latest = Ctor.options; const sealed = Ctor.sealedOptions; for (const key in latest) { if (latest[key] !== sealed[key]) { if (!modified) modified = {}; modified[key] = latest[key]; } } return modified } function Vue (options) { if (!(this instanceof Vue) ) { warn('Vue is a constructor and should be called with the `new` keyword'); } this._init(options); } initMixin(Vue); stateMixin(Vue); eventsMixin(Vue); lifecycleMixin(Vue); renderMixin(Vue); /* */ function initUse (Vue) { Vue.use = function (plugin) { const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])); if (installedPlugins.indexOf(plugin) > -1) { return this } // additional parameters const args = toArray(arguments, 1); args.unshift(this); if (typeof plugin.install === 'function') { plugin.install.apply(plugin, args); } else if (typeof plugin === 'function') { plugin.apply(null, args); } installedPlugins.push(plugin); return this }; } /* */ function initMixin$1 (Vue) { Vue.mixin = function (mixin) { this.options = mergeOptions(this.options, mixin); return this }; } /* */ 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; let cid = 1; /** * Class inheritance */ Vue.extend = function (extendOptions) { extendOptions = extendOptions || {}; const Super = this; const SuperId = Super.cid; const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {}); if (cachedCtors[SuperId]) { return cachedCtors[SuperId] } const name = extendOptions.name || Super.options.name; if (name) { validateComponentName(name); } const 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; // For props and computed properties, we define the proxy getters on // the Vue instances at extension time, on the extended prototype. This // avoids Object.defineProperty calls for each instance created. if (Sub.options.props) { initProps$1(Sub); } if (Sub.options.computed) { initComputed$1(Sub); } // allow further extension/mixin/plugin usage Sub.extend = Super.extend; Sub.mixin = Super.mixin; Sub.use = Super.use; // create asset registers, so extended classes // can have their private assets too. ASSET_TYPES.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; Sub.sealedOptions = extend({}, Sub.options); // cache constructor cachedCtors[SuperId] = Sub; return Sub }; } function initProps$1 (Comp) { const props = Comp.options.props; for (const key in props) { proxy(Comp.prototype, `_props`, key); } } function initComputed$1 (Comp) { const computed = Comp.options.computed; for (const key in computed) { defineComputed(Comp.prototype, key, computed[key]); } } /* */ function initAssetRegisters (Vue) { /** * Create asset registration methods. */ ASSET_TYPES.forEach(type => { Vue[type] = function ( id, definition ) { if (!definition) { return this.options[type + 's'][id] } else { /* istanbul ignore if */ if (type === 'component') { validateComponentName(id); } if (type === 'component' && isPlainObject(definition)) { definition.name = definition.name || id; definition = this.options._base.extend(definition); } if (type === 'directive' && typeof definition === 'function') { definition = { bind: definition, update: definition }; } this.options[type + 's'][id] = definition; return definition } }; }); } /* */ function getComponentName (opts) { return opts && (opts.Ctor.options.name || opts.tag) } function matches (pattern, name) { if (Array.isArray(pattern)) { return pattern.indexOf(name) > -1 } else if (typeof pattern === 'string') { return pattern.split(',').indexOf(name) > -1 } else if (isRegExp(pattern)) { return pattern.test(name) } /* istanbul ignore next */ return false } function pruneCache (keepAliveInstance, filter) { const { cache, keys, _vnode } = keepAliveInstance; for (const key in cache) { const cachedNode = cache[key]; if (cachedNode) { const name = getComponentName(cachedNode.componentOptions); if (name && !filter(name)) { pruneCacheEntry(cache, key, keys, _vnode); } } } } function pruneCacheEntry ( cache, key, keys, current ) { const cached$$1 = cache[key]; if (cached$$1 && (!current || cached$$1.tag !== current.tag)) { cached$$1.componentInstance.$destroy(); } cache[key] = null; remove(keys, key); } const patternTypes = [String, RegExp, Array]; var KeepAlive = { name: 'keep-alive', abstract: true, props: { include: patternTypes, exclude: patternTypes, max: [String, Number] }, created () { this.cache = Object.create(null); this.keys = []; }, destroyed () { for (const key in this.cache) { pruneCacheEntry(this.cache, key, this.keys); } }, mounted () { this.$watch('include', val => { pruneCache(this, name => matches(val, name)); }); this.$watch('exclude', val => { pruneCache(this, name => !matches(val, name)); }); }, render () { const slot = this.$slots.default; const vnode = getFirstComponentChild(slot); const componentOptions = vnode && vnode.componentOptions; if (componentOptions) { // check pattern const name = getComponentName(componentOptions); const { include, exclude } = this; if ( // not included (include && (!name || !matches(include, name))) || // excluded (exclude && name && matches(exclude, name)) ) { return vnode } const { cache, keys } = this; const key = vnode.key == null // same constructor may get registered as different local components // so cid alone is not enough (#3269) ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '') : vnode.key; if (cache[key]) { vnode.componentInstance = cache[key].componentInstance; // make current key freshest remove(keys, key); keys.push(key); } else { cache[key] = vnode; keys.push(key); // prune oldest entry if (this.max && keys.length > parseInt(this.max)) { pruneCacheEntry(cache, keys[0], keys, this._vnode); } } vnode.data.keepAlive = true; } return vnode || (slot && slot[0]) } }; var builtInComponents = { KeepAlive }; /* */ function initGlobalAPI (Vue) { // config const configDef = {}; configDef.get = () => config; { configDef.set = () => { warn( 'Do not replace the Vue.config object, set individual fields instead.' ); }; } Object.defineProperty(Vue, 'config', configDef); // exposed util methods. // NOTE: these are not considered part of the public API - avoid relying on // them unless you are aware of the risk. Vue.util = { warn, extend, mergeOptions, defineReactive: defineReactive$$1 }; Vue.set = set; Vue.delete = del; Vue.nextTick = nextTick; // 2.6 explicit observable API Vue.observable = (obj) => { observe(obj); return obj }; Vue.options = Object.create(null); ASSET_TYPES.forEach(type => { Vue.options[type + 's'] = Object.create(null); }); // this is used to identify the "base" constructor to extend all plain-object // components with in Weex's multi-instance scenarios. Vue.options._base = Vue; extend(Vue.options.components, builtInComponents); initUse(Vue); initMixin$1(Vue); initExtend(Vue); initAssetRegisters(Vue); } initGlobalAPI(Vue); Object.defineProperty(Vue.prototype, '$isServer', { get: isServerRendering }); Object.defineProperty(Vue.prototype, '$ssrContext', { get () { /* istanbul ignore next */ return this.$vnode && this.$vnode.ssrContext } }); // expose FunctionalRenderContext for ssr runtime helper installation Object.defineProperty(Vue, 'FunctionalRenderContext', { value: FunctionalRenderContext }); Vue.version = '2.6.0'; /* */ // these are reserved for web because they are directly compiled away // during template compilation const isReservedAttr = makeMap('style,class'); // attributes that should be using props for binding const acceptValue = makeMap('input,textarea,option,select,progress'); const mustUseProp = (tag, type, attr) => { return ( (attr === 'value' && acceptValue(tag)) && type !== 'button' || (attr === 'selected' && tag === 'option') || (attr === 'checked' && tag === 'input') || (attr === 'muted' && tag === 'video') ) }; const isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck'); const isValidContentEditableValue = makeMap('events,caret,typing,plaintext-only'); const convertEnumeratedValue = (key, value) => { return isFalsyAttrValue(value) || value === 'false' ? 'false' // allow arbitrary string value for contenteditable : key === 'contenteditable' && isValidContentEditableValue(value) ? value : 'true' }; const 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' ); const xlinkNS = 'http://www.w3.org/1999/xlink'; const isXlink = (name) => { return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink' }; const getXlinkProp = (name) => { return isXlink(name) ? name.slice(6, name.length) : '' }; const isFalsyAttrValue = (val) => { return val == null || val === false }; /* */ function genClassForVnode (vnode) { let data = vnode.data; let parentNode = vnode; let childNode = vnode; while (isDef(childNode.componentInstance)) { childNode = childNode.componentInstance._vnode; if (childNode && childNode.data) { data = mergeClassData(childNode.data, data); } } while (isDef(parentNode = parentNode.parent)) { if (parentNode && parentNode.data) { data = mergeClassData(data, parentNode.data); } } return renderClass(data.staticClass, data.class) } function mergeClassData (child, parent) { return { staticClass: concat(child.staticClass, parent.staticClass), class: isDef(child.class) ? [child.class, parent.class] : parent.class } } function renderClass ( staticClass, dynamicClass ) { if (isDef(staticClass) || isDef(dynamicClass)) { return concat(staticClass, stringifyClass(dynamicClass)) } /* istanbul ignore next */ return '' } function concat (a, b) { return a ? b ? (a + ' ' + b) : a : (b || '') } function stringifyClass (value) { if (Array.isArray(value)) { return stringifyArray(value) } if (isObject(value)) { return stringifyObject(value) } if (typeof value === 'string') { return value } /* istanbul ignore next */ return '' } function stringifyArray (value) { let res = ''; let stringified; for (let i = 0, l = value.length; i < l; i++) { if (isDef(stringified = stringifyClass(value[i])) && stringified !== '') { if (res) res += ' '; res += stringified; } } return res } function stringifyObject (value) { let res = ''; for (const key in value) { if (value[key]) { if (res) res += ' '; res += key; } } return res } /* */ const namespaceMap = { svg: 'http://www.w3.org/2000/svg', math: 'http://www.w3.org/1998/Math/MathML' }; const isHTMLTag = makeMap( 'html,body,base,head,link,meta,style,title,' + 'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' + 'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' + 'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' + 's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' + 'embed,object,param,source,canvas,script,noscript,del,ins,' + 'caption,col,colgroup,table,thead,tbody,td,th,tr,' + 'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' + 'output,progress,select,textarea,' + 'details,dialog,menu,menuitem,summary,' + 'content,element,shadow,template,blockquote,iframe,tfoot' ); // this map is intentionally selective, only covering SVG elements that may // contain child elements. const isSVG = makeMap( 'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' + 'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' + 'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view', true ); const isPreTag = (tag) => tag === 'pre'; const isReservedTag = (tag) => { return isHTMLTag(tag) || isSVG(tag) }; function getTagNamespace (tag) { if (isSVG(tag)) { return 'svg' } // basic support for MathML // note it doesn't support other MathML elements being component roots if (tag === 'math') { return 'math' } } const unknownElementCache = Object.create(null); function isUnknownElement (tag) { /* istanbul ignore if */ if (!inBrowser) { return true } if (isReservedTag(tag)) { return false } tag = tag.toLowerCase(); /* istanbul ignore if */ if (unknownElementCache[tag] != null) { return unknownElementCache[tag] } const el = document.createElement(tag); if (tag.indexOf('-') > -1) { // http://stackoverflow.com/a/28210364/1070244 return (unknownElementCache[tag] = ( el.constructor === window.HTMLUnknownElement || el.constructor === window.HTMLElement )) } else { return (unknownElementCache[tag] = /HTMLUnknownElement/.test(el.toString())) } } const isTextInputType = makeMap('text,number,password,search,email,tel,url'); /* */ /** * Query an element selector if it's not an element already. */ function query (el) { if (typeof el === 'string') { const selected = document.querySelector(el); if (!selected) { warn( 'Cannot find element: ' + el ); return document.createElement('div') } return selected } else { return el } } /* */ function createElement$1 (tagName, vnode) { const elm = document.createElement(tagName); if (tagName !== 'select') { return elm } // false or null will remove the attribute but undefined will not if (vnode.data && vnode.data.attrs && vnode.data.attrs.multiple !== undefined) { elm.setAttribute('multiple', 'multiple'); } return elm } function createElementNS (namespace, tagName) { return document.createElementNS(namespaceMap[namespace], tagName) } function createTextNode (text) { return document.createTextNode(text) } function createComment (text) { return document.createComment(text) } function insertBefore (parentNode, newNode, referenceNode) { parentNode.insertBefore(newNode, referenceNode); } function removeChild (node, child) { node.removeChild(child); } function appendChild (node, child) { node.appendChild(child); } function parentNode (node) { return node.parentNode } function nextSibling (node) { return node.nextSibling } function tagName (node) { return node.tagName } function setTextContent (node, text) { node.textContent = text; } function setStyleScope (node, scopeId) { node.setAttribute(scopeId, ''); } var nodeOps = /*#__PURE__*/Object.freeze({ createElement: createElement$1, createElementNS: createElementNS, createTextNode: createTextNode, createComment: createComment, insertBefore: insertBefore, removeChild: removeChild, appendChild: appendChild, parentNode: parentNode, nextSibling: nextSibling, tagName: tagName, setTextContent: setTextContent, setStyleScope: setStyleScope }); /* */ var ref = { create (_, vnode) { registerRef(vnode); }, update (oldVnode, vnode) { if (oldVnode.data.ref !== vnode.data.ref) { registerRef(oldVnode, true); registerRef(vnode); } }, destroy (vnode) { registerRef(vnode, true); } }; function registerRef (vnode, isRemoval) { const key = vnode.data.ref; if (!isDef(key)) return const vm = vnode.context; const ref = vnode.componentInstance || vnode.elm; const refs = vm.$refs; if (isRemoval) { if (Array.isArray(refs[key])) { remove(refs[key], ref); } else if (refs[key] === ref) { refs[key] = undefined; } } else { if (vnode.data.refInFor) { if (!Array.isArray(refs[key])) { refs[key] = [ref]; } else if (refs[key].indexOf(ref) < 0) { // $flow-disable-line refs[key].push(ref); } } else { refs[key] = ref; } } } /** * Virtual DOM patching algorithm based on Snabbdom by * Simon Friis Vindum (@paldepind) * Licensed under the MIT License * https://github.com/paldepind/snabbdom/blob/master/LICENSE * * modified by Evan You (@yyx990803) * * Not type-checking this because this file is perf-critical and the cost * of making flow understand it is not worth it. */ const emptyNode = new VNode('', {}, []); const hooks = ['create', 'activate', 'update', 'remove', 'destroy']; function sameVnode (a, b) { return ( a.key === b.key && ( ( a.tag === b.tag && a.isComment === b.isComment && isDef(a.data) === isDef(b.data) && sameInputType(a, b) ) || ( isTrue(a.isAsyncPlaceholder) && a.asyncFactory === b.asyncFactory && isUndef(b.asyncFactory.error) ) ) ) } function sameInputType (a, b) { if (a.tag !== 'input') return true let i; const typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type; const typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type; return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB) } function createKeyToOldIdx (children, beginIdx, endIdx) { let i, key; const map = {}; for (i = beginIdx; i <= endIdx; ++i) { key = children[i].key; if (isDef(key)) map[key] = i; } return map } function createPatchFunction (backend) { let i, j; const cbs = {}; const { modules, nodeOps } = backend; for (i = 0; i < hooks.length; ++i) { cbs[hooks[i]] = []; for (j = 0; j < modules.length; ++j) { if (isDef(modules[j][hooks[i]])) { cbs[hooks[i]].push(modules[j][hooks[i]]); } } } function emptyNodeAt (elm) { return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm) } function createRmCb (childElm, listeners) { function remove$$1 () { if (--remove$$1.listeners === 0) { removeNode(childElm); } } remove$$1.listeners = listeners; return remove$$1 } function removeNode (el) { const parent = nodeOps.parentNode(el); // element may have already been removed due to v-html / v-text if (isDef(parent)) { nodeOps.removeChild(parent, el); } } function isUnknownElement$$1 (vnode, inVPre) { return ( !inVPre && !vnode.ns && !( config.ignoredElements.length && config.ignoredElements.some(ignore => { return isRegExp(ignore) ? ignore.test(vnode.tag) : ignore === vnode.tag }) ) && config.isUnknownElement(vnode.tag) ) } let creatingElmInVPre = 0; function createElm ( vnode, insertedVnodeQueue, parentElm, refElm, nested, ownerArray, index ) { if (isDef(vnode.elm) && isDef(ownerArray)) { // This vnode was used in a previous render! // now it's used as a new node, overwriting its elm would cause // potential patch errors down the road when it's used as an insertion // reference node. Instead, we clone the node on-demand before creating // associated DOM element for it. vnode = ownerArray[index] = cloneVNode(vnode); } vnode.isRootInsert = !nested; // for transition enter check if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) { return } const data = vnode.data; const children = vnode.children; const tag = vnode.tag; if (isDef(tag)) { { if (data && data.pre) { creatingElmInVPre++; } if (isUnknownElement$$1(vnode, creatingElmInVPre)) { warn( 'Unknown custom element: <' + tag + '> - did you ' + 'register the component correctly? For recursive components, ' + 'make sure to provide the "name" option.', vnode.context ); } } vnode.elm = vnode.ns ? nodeOps.createElementNS(vnode.ns, tag) : nodeOps.createElement(tag, vnode); setScope(vnode); /* istanbul ignore if */ { createChildren(vnode, children, insertedVnodeQueue); if (isDef(data)) { invokeCreateHooks(vnode, insertedVnodeQueue); } insert(parentElm, vnode.elm, refElm); } if (data && data.pre) { creatingElmInVPre--; } } else if (isTrue(vnode.isComment)) { vnode.elm = nodeOps.createComment(vnode.text); insert(parentElm, vnode.elm, refElm); } else { vnode.elm = nodeOps.createTextNode(vnode.text); insert(parentElm, vnode.elm, refElm); } } function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) { let i = vnode.data; if (isDef(i)) { const isReactivated = isDef(vnode.componentInstance) && i.keepAlive; if (isDef(i = i.hook) && isDef(i = i.init)) { i(vnode, false /* hydrating */); } // after calling the init hook, if the vnode is a child component // it should've created a child instance and mounted it. the child // component also has set the placeholder vnode's elm. // in that case we can just return the element and be done. if (isDef(vnode.componentInstance)) { initComponent(vnode, insertedVnodeQueue); insert(parentElm, vnode.elm, refElm); if (isTrue(isReactivated)) { reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm); } return true } } } function initComponent (vnode, insertedVnodeQueue) { if (isDef(vnode.data.pendingInsert)) { insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert); vnode.data.pendingInsert = null; } vnode.elm = vnode.componentInstance.$el; if (isPatchable(vnode)) { invokeCreateHooks(vnode, insertedVnodeQueue); setScope(vnode); } else { // empty component root. // skip all element-related modules except for ref (#3455) registerRef(vnode); // make sure to invoke the insert hook insertedVnodeQueue.push(vnode); } } function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) { let i; // hack for #4339: a reactivated component with inner transition // does not trigger because the inner node's created hooks are not called // again. It's not ideal to involve module-specific logic in here but // there doesn't seem to be a better way to do it. let innerNode = vnode; while (innerNode.componentInstance) { innerNode = innerNode.componentInstance._vnode; if (isDef(i = innerNode.data) && isDef(i = i.transition)) { for (i = 0; i < cbs.activate.length; ++i) { cbs.activate[i](emptyNode, innerNode); } insertedVnodeQueue.push(innerNode); break } } // unlike a newly created component, // a reactivated keep-alive component doesn't insert itself insert(parentElm, vnode.elm, refElm); } function insert (parent, elm, ref$$1) { if (isDef(parent)) { if (isDef(ref$$1)) { if (nodeOps.parentNode(ref$$1) === parent) { nodeOps.insertBefore(parent, elm, ref$$1); } } else { nodeOps.appendChild(parent, elm); } } } function createChildren (vnode, children, insertedVnodeQueue) { if (Array.isArray(children)) { { checkDuplicateKeys(children); } for (let i = 0; i < children.length; ++i) { createElm(children[i], insertedVnodeQueue, vnode.elm, null, true, children, i); } } else if (isPrimitive(vnode.text)) { nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text))); } } function isPatchable (vnode) { while (vnode.componentInstance) { vnode = vnode.componentInstance._vnode; } return isDef(vnode.tag) } function invokeCreateHooks (vnode, insertedVnodeQueue) { for (let i = 0; i < cbs.create.length; ++i) { cbs.create[i](emptyNode, vnode); } i = vnode.data.hook; // Reuse variable if (isDef(i)) { if (isDef(i.create)) i.create(emptyNode, vnode); if (isDef(i.insert)) insertedVnodeQueue.push(vnode); } } // set scope id attribute for scoped CSS. // this is implemented as a special case to avoid the overhead // of going through the normal attribute patching process. function setScope (vnode) { let i; if (isDef(i = vnode.fnScopeId)) { nodeOps.setStyleScope(vnode.elm, i); } else { let ancestor = vnode; while (ancestor) { if (isDef(i = ancestor.context) && isDef(i = i.$options._scopeId)) { nodeOps.setStyleScope(vnode.elm, i); } ancestor = ancestor.parent; } } // for slot content they should also get the scopeId from the host instance. if (isDef(i = activeInstance) && i !== vnode.context && i !== vnode.fnContext && isDef(i = i.$options._scopeId) ) { nodeOps.setStyleScope(vnode.elm, i); } } function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) { for (; startIdx <= endIdx; ++startIdx) { createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm, false, vnodes, startIdx); } } function invokeDestroyHook (vnode) { let i, j; const data = vnode.data; if (isDef(data)) { if (isDef(i = data.hook) && isDef(i = i.destroy)) i(vnode); for (i = 0; i < cbs.destroy.length; ++i) cbs.destroy[i](vnode); } if (isDef(i = vnode.children)) { for (j = 0; j < vnode.children.length; ++j) { invokeDestroyHook(vnode.children[j]); } } } function removeVnodes (parentElm, vnodes, startIdx, endIdx) { for (; startIdx <= endIdx; ++startIdx) { const ch = vnodes[startIdx]; if (isDef(ch)) { if (isDef(ch.tag)) { removeAndInvokeRemoveHook(ch); invokeDestroyHook(ch); } else { // Text node removeNode(ch.elm); } } } } function removeAndInvokeRemoveHook (vnode, rm) { if (isDef(rm) || isDef(vnode.data)) { let i; const listeners = cbs.remove.length + 1; if (isDef(rm)) { // we have a recursively passed down rm callback // increase the listeners count rm.listeners += listeners; } else { // directly removing rm = createRmCb(vnode.elm, listeners); } // recursively invoke hooks on child component root node if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) { removeAndInvokeRemoveHook(i, rm); } for (i = 0; i < cbs.remove.length; ++i) { cbs.remove[i](vnode, rm); } if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) { i(vnode, rm); } else { rm(); } } else { removeNode(vnode.elm); } } function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) { let oldStartIdx = 0; let newStartIdx = 0; let oldEndIdx = oldCh.length - 1; let oldStartVnode = oldCh[0]; let oldEndVnode = oldCh[oldEndIdx]; let newEndIdx = newCh.length - 1; let newStartVnode = newCh[0]; let newEndVnode = newCh[newEndIdx]; let oldKeyToIdx, idxInOld, vnodeToMove, refElm; // removeOnly is a special flag used only by // to ensure removed elements stay in correct relative positions // during leaving transitions const canMove = !removeOnly; { checkDuplicateKeys(newCh); } while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { if (isUndef(oldStartVnode)) { oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left } else if (isUndef(oldEndVnode)) { oldEndVnode = oldCh[--oldEndIdx]; } else if (sameVnode(oldStartVnode, newStartVnode)) { patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx); oldStartVnode = oldCh[++oldStartIdx]; newStartVnode = newCh[++newStartIdx]; } else if (sameVnode(oldEndVnode, newEndVnode)) { patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx); oldEndVnode = oldCh[--oldEndIdx]; newEndVnode = newCh[--newEndIdx]; } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx); canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm)); oldStartVnode = oldCh[++oldStartIdx]; newEndVnode = newCh[--newEndIdx]; } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx); canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm); oldEndVnode = oldCh[--oldEndIdx]; newStartVnode = newCh[++newStartIdx]; } else { if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); idxInOld = isDef(newStartVnode.key) ? oldKeyToIdx[newStartVnode.key] : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx); if (isUndef(idxInOld)) { // New element createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx); } else { vnodeToMove = oldCh[idxInOld]; if (sameVnode(vnodeToMove, newStartVnode)) { patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx); oldCh[idxInOld] = undefined; canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm); } else { // same key but different element. treat as new element createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx); } } newStartVnode = newCh[++newStartIdx]; } } if (oldStartIdx > oldEndIdx) { refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm; addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue); } else if (newStartIdx > newEndIdx) { removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx); } } function checkDuplicateKeys (children) { const seenKeys = {}; for (let i = 0; i < children.length; i++) { const vnode = children[i]; const key = vnode.key; if (isDef(key)) { if (seenKeys[key]) { warn( `Duplicate keys detected: '${key}'. This may cause an update error.`, vnode.context ); } else { seenKeys[key] = true; } } } } function findIdxInOld (node, oldCh, start, end) { for (let i = start; i < end; i++) { const c = oldCh[i]; if (isDef(c) && sameVnode(node, c)) return i } } function patchVnode ( oldVnode, vnode, insertedVnodeQueue, ownerArray, index, removeOnly ) { if (oldVnode === vnode) { return } if (isDef(vnode.elm) && isDef(ownerArray)) { // clone reused vnode vnode = ownerArray[index] = cloneVNode(vnode); } const elm = vnode.elm = oldVnode.elm; if (isTrue(oldVnode.isAsyncPlaceholder)) { if (isDef(vnode.asyncFactory.resolved)) { hydrate(oldVnode.elm, vnode, insertedVnodeQueue); } else { vnode.isAsyncPlaceholder = true; } return } // reuse element for static trees. // note we only do this if the vnode is cloned - // if the new node is not cloned it means the render functions have been // reset by the hot-reload-api and we need to do a proper re-render. if (isTrue(vnode.isStatic) && isTrue(oldVnode.isStatic) && vnode.key === oldVnode.key && (isTrue(vnode.isCloned) || isTrue(vnode.isOnce)) ) { vnode.componentInstance = oldVnode.componentInstance; return } let i; const data = vnode.data; if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) { i(oldVnode, vnode); } const oldCh = oldVnode.children; const ch = vnode.children; if (isDef(data) && isPatchable(vnode)) { for (i = 0; i < cbs.update.length; ++i) cbs.update[i](oldVnode, vnode); if (isDef(i = data.hook) && isDef(i = i.update)) i(oldVnode, vnode); } if (isUndef(vnode.text)) { if (isDef(oldCh) && isDef(ch)) { if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly); } else if (isDef(ch)) { { checkDuplicateKeys(ch); } if (isDef(oldVnode.text)) nodeOps.setTextContent(elm, ''); addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue); } else if (isDef(oldCh)) { removeVnodes(elm, oldCh, 0, oldCh.length - 1); } else if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); } } else if (oldVnode.text !== vnode.text) { nodeOps.setTextContent(elm, vnode.text); } if (isDef(data)) { if (isDef(i = data.hook) && isDef(i = i.postpatch)) i(oldVnode, vnode); } } function invokeInsertHook (vnode, queue, initial) { // delay insert hooks for component root nodes, invoke them after the // element is really inserted if (isTrue(initial) && isDef(vnode.parent)) { vnode.parent.data.pendingInsert = queue; } else { for (let i = 0; i < queue.length; ++i) { queue[i].data.hook.insert(queue[i]); } } } let hydrationBailed = false; // list of modules that can skip create hook during hydration because they // are already rendered on the client or has no need for initialization // Note: style is excluded because it relies on initial clone for future // deep updates (#7063). const isRenderedModule = makeMap('attrs,class,staticClass,staticStyle,key'); // Note: this is a browser-only function so we can assume elms are DOM nodes. function hydrate (elm, vnode, insertedVnodeQueue, inVPre) { let i; const { tag, data, children } = vnode; inVPre = inVPre || (data && data.pre); vnode.elm = elm; if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) { vnode.isAsyncPlaceholder = true; return true } // assert node match { if (!assertNodeMatch(elm, vnode, inVPre)) { return false } } if (isDef(data)) { if (isDef(i = data.hook) && isDef(i = i.init)) i(vnode, true /* hydrating */); if (isDef(i = vnode.componentInstance)) { // child component. it should have hydrated its own tree. initComponent(vnode, insertedVnodeQueue); return true } } if (isDef(tag)) { if (isDef(children)) { // empty element, allow client to pick up and populate children if (!elm.hasChildNodes()) { createChildren(vnode, children, insertedVnodeQueue); } else { // v-html and domProps: innerHTML if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) { if (i !== elm.innerHTML) { /* istanbul ignore if */ if (typeof console !== 'undefined' && !hydrationBailed ) { hydrationBailed = true; console.warn('Parent: ', elm); console.warn('server innerHTML: ', i); console.warn('client innerHTML: ', elm.innerHTML); } return false } } else { // iterate and compare children lists let childrenMatch = true; let childNode = elm.firstChild; for (let i = 0; i < children.length; i++) { if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue, inVPre)) { childrenMatch = false; break } childNode = childNode.nextSibling; } // if childNode is not null, it means the actual childNodes list is // longer than the virtual children list. if (!childrenMatch || childNode) { /* istanbul ignore if */ if (typeof console !== 'undefined' && !hydrationBailed ) { hydrationBailed = true; console.warn('Parent: ', elm); console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children); } return false } } } } if (isDef(data)) { let fullInvoke = false; for (const key in data) { if (!isRenderedModule(key)) { fullInvoke = true; invokeCreateHooks(vnode, insertedVnodeQueue); break } } if (!fullInvoke && data['class']) { // ensure collecting deps for deep class bindings for future updates traverse(data['class']); } } } else if (elm.data !== vnode.text) { elm.data = vnode.text; } return true } function assertNodeMatch (node, vnode, inVPre) { if (isDef(vnode.tag)) { return vnode.tag.indexOf('vue-component') === 0 || ( !isUnknownElement$$1(vnode, inVPre) && vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase()) ) } else { return node.nodeType === (vnode.isComment ? 8 : 3) } } return function patch (oldVnode, vnode, hydrating, removeOnly) { if (isUndef(vnode)) { if (isDef(oldVnode)) invokeDestroyHook(oldVnode); return } let isInitialPatch = false; const insertedVnodeQueue = []; if (isUndef(oldVnode)) { // empty mount (likely as component), create new root element isInitialPatch = true; createElm(vnode, insertedVnodeQueue); } else { const isRealElement = isDef(oldVnode.nodeType); if (!isRealElement && sameVnode(oldVnode, vnode)) { // patch existing root node patchVnode(oldVnode, vnode, insertedVnodeQueue, null, null, removeOnly); } else { if (isRealElement) { // mounting to a real element // check if this is server-rendered content and if we can perform // a successful hydration. if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) { oldVnode.removeAttribute(SSR_ATTR); hydrating = true; } if (isTrue(hydrating)) { if (hydrate(oldVnode, vnode, insertedVnodeQueue)) { invokeInsertHook(vnode, insertedVnodeQueue, true); return oldVnode } else { warn( 'The client-side rendered virtual DOM tree is not matching ' + 'server-rendered content. This is likely caused by incorrect ' + 'HTML markup, for example nesting block-level elements inside ' + '
, 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); } // replacing existing element const oldElm = oldVnode.elm; const parentElm = nodeOps.parentNode(oldElm); // create new node createElm( vnode, insertedVnodeQueue, // extremely rare edge case: do not insert if old element is in a // leaving transition. Only happens when combining transition + // keep-alive + HOCs. (#4590) oldElm._leaveCb ? null : parentElm, nodeOps.nextSibling(oldElm) ); // update parent placeholder node element, recursively if (isDef(vnode.parent)) { let ancestor = vnode.parent; const patchable = isPatchable(vnode); while (ancestor) { for (let i = 0; i < cbs.destroy.length; ++i) { cbs.destroy[i](ancestor); } ancestor.elm = vnode.elm; if (patchable) { for (let i = 0; i < cbs.create.length; ++i) { cbs.create[i](emptyNode, ancestor); } // #6513 // invoke insert hooks that may have been merged by create hooks. // e.g. for directives that uses the "inserted" hook. const insert = ancestor.data.hook.insert; if (insert.merged) { // start at index 1 to avoid re-invoking component mounted hook for (let i = 1; i < insert.fns.length; i++) { insert.fns[i](); } } } else { registerRef(ancestor); } ancestor = ancestor.parent; } } // destroy old node if (isDef(parentElm)) { removeVnodes(parentElm, [oldVnode], 0, 0); } else if (isDef(oldVnode.tag)) { invokeDestroyHook(oldVnode); } } } invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch); return vnode.elm } } /* */ var directives = { create: updateDirectives, update: updateDirectives, destroy: function unbindDirectives (vnode) { updateDirectives(vnode, emptyNode); } }; function updateDirectives (oldVnode, vnode) { if (oldVnode.data.directives || vnode.data.directives) { _update(oldVnode, vnode); } } function _update (oldVnode, vnode) { const isCreate = oldVnode === emptyNode; const isDestroy = vnode === emptyNode; const oldDirs = normalizeDirectives$1(oldVnode.data.directives, oldVnode.context); const newDirs = normalizeDirectives$1(vnode.data.directives, vnode.context); const dirsWithInsert = []; const dirsWithPostpatch = []; let key, oldDir, dir; for (key in newDirs) { oldDir = oldDirs[key]; dir = newDirs[key]; if (!oldDir) { // new directive, bind callHook$1(dir, 'bind', vnode, oldVnode); if (dir.def && dir.def.inserted) { dirsWithInsert.push(dir); } } else { // existing directive, update dir.oldValue = oldDir.value; dir.oldArg = oldDir.arg; callHook$1(dir, 'update', vnode, oldVnode); if (dir.def && dir.def.componentUpdated) { dirsWithPostpatch.push(dir); } } } if (dirsWithInsert.length) { const callInsert = () => { for (let i = 0; i < dirsWithInsert.length; i++) { callHook$1(dirsWithInsert[i], 'inserted', vnode, oldVnode); } }; if (isCreate) { mergeVNodeHook(vnode, 'insert', callInsert); } else { callInsert(); } } if (dirsWithPostpatch.length) { mergeVNodeHook(vnode, 'postpatch', () => { for (let i = 0; i < dirsWithPostpatch.length; i++) { callHook$1(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode); } }); } if (!isCreate) { for (key in oldDirs) { if (!newDirs[key]) { // no longer present, unbind callHook$1(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy); } } } } const emptyModifiers = Object.create(null); function normalizeDirectives$1 ( dirs, vm ) { const res = Object.create(null); if (!dirs) { // $flow-disable-line return res } let i, dir; for (i = 0; i < dirs.length; i++) { dir = dirs[i]; if (!dir.modifiers) { // $flow-disable-line dir.modifiers = emptyModifiers; } res[getRawDirName(dir)] = dir; dir.def = resolveAsset(vm.$options, 'directives', dir.name, true); } // $flow-disable-line return res } function getRawDirName (dir) { return dir.rawName || `${dir.name}.${Object.keys(dir.modifiers || {}).join('.')}` } function callHook$1 (dir, hook, vnode, oldVnode, isDestroy) { const fn = dir.def && dir.def[hook]; if (fn) { try { fn(vnode.elm, dir, vnode, oldVnode, isDestroy); } catch (e) { handleError(e, vnode.context, `directive ${dir.name} ${hook} hook`); } } } var baseModules = [ ref, directives ]; /* */ function updateAttrs (oldVnode, vnode) { const opts = vnode.componentOptions; if (isDef(opts) && opts.Ctor.options.inheritAttrs === false) { return } if (isUndef(oldVnode.data.attrs) && isUndef(vnode.data.attrs)) { return } let key, cur, old; const elm = vnode.elm; const oldAttrs = oldVnode.data.attrs || {}; let attrs = vnode.data.attrs || {}; // clone observed objects, as the user probably wants to mutate it if (isDef(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); } } // #4391: in IE9, setting type can reset value for input[type=radio] // #6666: IE/Edge forces progress value down to 1 before setting a max /* istanbul ignore if */ if ((isIE || isEdge) && attrs.value !== oldAttrs.value) { setAttr(elm, 'value', attrs.value); } for (key in oldAttrs) { if (isUndef(attrs[key])) { if (isXlink(key)) { elm.removeAttributeNS(xlinkNS, getXlinkProp(key)); } else if (!isEnumeratedAttr(key)) { elm.removeAttribute(key); } } } } function setAttr (el, key, value) { if (el.tagName.indexOf('-') > -1) { baseSetAttr(el, key, value); } else if (isBooleanAttr(key)) { // set attribute for blank value // e.g. Select one if (isFalsyAttrValue(value)) { el.removeAttribute(key); } else { // technically allowfullscreen is a boolean attribute for
RetroSearch is an open source project built by @garambo
| Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4