From 4a9ce30a841b741d5d960810eccdef5259d1cf21 Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Fri, 18 Sep 2020 14:17:50 +0800 Subject: [PATCH] chore: merge --- packages/uni-h5-vue/dist/vue.runtime.esm.js | 18191 ++++++++--------- packages/uni-h5-vue/lib/vue.runtime.esm.js | 18353 ++++++++---------- packages/uni-mp-vue/dist/vue.runtime.esm.js | 175 +- packages/uni-mp-vue/lib/vue.runtime.esm.js | 175 +- 4 files changed, 17429 insertions(+), 19465 deletions(-) diff --git a/packages/uni-h5-vue/dist/vue.runtime.esm.js b/packages/uni-h5-vue/dist/vue.runtime.esm.js index d4438e51f..6d9bc59c2 100644 --- a/packages/uni-h5-vue/dist/vue.runtime.esm.js +++ b/packages/uni-h5-vue/dist/vue.runtime.esm.js @@ -1,4370 +1,4085 @@ -import { isSymbol, extend, isObject, toRawType, def, isArray, isString, isFunction, isPromise, capitalize, EMPTY_ARR, normalizeClass, normalizeStyle, isOn, remove, EMPTY_OBJ, NOOP, isGloballyWhitelisted, toNumber, invokeArrayFns, looseIndexOf, looseEqual, hyphenate, isHTMLTag, isSVGTag, isIntegerKey, hasOwn, hasChanged, camelize, getGlobalThis, isReservedProp, NO, isModelListener, makeMap, isSpecialBooleanAttr } from '@vue/shared'; +import { isSymbol, extend, isMap, isObject, toRawType, def, isArray, isString, isFunction, isPromise, capitalize, EMPTY_ARR, normalizeClass, normalizeStyle, isOn, remove, EMPTY_OBJ, NOOP, isGloballyWhitelisted, toNumber, invokeArrayFns, looseIndexOf, isSet, looseHas, looseEqual, hyphenate, isHTMLTag, isSVGTag, isIntegerKey, hasOwn, hasChanged, camelize, getGlobalThis, isReservedProp, NO, isModelListener, makeMap, isSpecialBooleanAttr } from '@vue/shared'; export { camelize, capitalize, toDisplayString } from '@vue/shared'; -const targetMap = new WeakMap(); -const effectStack = []; -let activeEffect; -const ITERATE_KEY = Symbol( - process.env.NODE_ENV !== 'production' ? 'iterate' : '' -); -const MAP_KEY_ITERATE_KEY = Symbol( - process.env.NODE_ENV !== 'production' ? 'Map key iterate' : '' -); -function isEffect(fn) { - return fn && fn._isEffect === true -} -function effect(fn, options = EMPTY_OBJ) { - if (isEffect(fn)) { - fn = fn.raw; - } - const effect = createReactiveEffect(fn, options); - if (!options.lazy) { - effect(); - } - return effect -} -function stop(effect) { - if (effect.active) { - cleanup(effect); - if (effect.options.onStop) { - effect.options.onStop(); - } - effect.active = false; - } -} -let uid = 0; -function createReactiveEffect(fn, options) { - const effect = function reactiveEffect() { - if (!effect.active) { - return options.scheduler ? undefined : fn() - } - if (!effectStack.includes(effect)) { - cleanup(effect); - try { - enableTracking(); - effectStack.push(effect); - activeEffect = effect; - return fn() - } finally { - effectStack.pop(); - resetTracking(); - activeEffect = effectStack[effectStack.length - 1]; - } - } - }; - effect.id = uid++; - effect._isEffect = true; - effect.active = true; - effect.raw = fn; - effect.deps = []; - effect.options = options; - return effect -} -function cleanup(effect) { - const { deps } = effect; - if (deps.length) { - for (let i = 0; i < deps.length; i++) { - deps[i].delete(effect); - } - deps.length = 0; - } -} -let shouldTrack = true; -const trackStack = []; -function pauseTracking() { - trackStack.push(shouldTrack); - shouldTrack = false; -} -function enableTracking() { - trackStack.push(shouldTrack); - shouldTrack = true; -} -function resetTracking() { - const last = trackStack.pop(); - shouldTrack = last === undefined ? true : last; -} -function track(target, type, key) { - if (!shouldTrack || activeEffect === undefined) { - return - } - let depsMap = targetMap.get(target); - if (!depsMap) { - targetMap.set(target, (depsMap = new Map())); - } - let dep = depsMap.get(key); - if (!dep) { - depsMap.set(key, (dep = new Set())); - } - if (!dep.has(activeEffect)) { - dep.add(activeEffect); - activeEffect.deps.push(dep); - if (process.env.NODE_ENV !== 'production' && activeEffect.options.onTrack) { - activeEffect.options.onTrack({ - effect: activeEffect, - target, - type, - key - }); - } - } -} -function trigger(target, type, key, newValue, oldValue, oldTarget) { - const depsMap = targetMap.get(target); - if (!depsMap) { - // never been tracked - return - } - const effects = new Set(); - const add = effectsToAdd => { - if (effectsToAdd) { - effectsToAdd.forEach(effect => { - if (effect !== activeEffect) { - effects.add(effect); - } - }); - } - }; - if (type === 'clear' /* CLEAR */) { - // collection being cleared - // trigger all effects for target - depsMap.forEach(add); - } else if (key === 'length' && isArray(target)) { - depsMap.forEach((dep, key) => { - if (key === 'length' || key >= newValue) { - add(dep); - } - }); - } else { - // schedule runs for SET | ADD | DELETE - if (key !== void 0) { - add(depsMap.get(key)); - } - // also run for iteration key on ADD | DELETE | Map.SET - const shouldTriggerIteration = - (type === 'add' /* ADD */ && (!isArray(target) || isIntegerKey(key))) || - (type === 'delete' /* DELETE */ && !isArray(target)); - if ( - shouldTriggerIteration || - (type === 'set' /* SET */ && target instanceof Map) - ) { - add(depsMap.get(isArray(target) ? 'length' : ITERATE_KEY)); - } - if (shouldTriggerIteration && target instanceof Map) { - add(depsMap.get(MAP_KEY_ITERATE_KEY)); - } - } - const run = effect => { - if (process.env.NODE_ENV !== 'production' && effect.options.onTrigger) { - effect.options.onTrigger({ - effect, - target, - key, - type, - newValue, - oldValue, - oldTarget - }); - } - if (effect.options.scheduler) { - effect.options.scheduler(effect); - } else { - effect(); - } - }; - effects.forEach(run); +const targetMap = new WeakMap(); +const effectStack = []; +let activeEffect; +const ITERATE_KEY = Symbol((process.env.NODE_ENV !== 'production') ? 'iterate' : ''); +const MAP_KEY_ITERATE_KEY = Symbol((process.env.NODE_ENV !== 'production') ? 'Map key iterate' : ''); +function isEffect(fn) { + return fn && fn._isEffect === true; +} +function effect(fn, options = EMPTY_OBJ) { + if (isEffect(fn)) { + fn = fn.raw; + } + const effect = createReactiveEffect(fn, options); + if (!options.lazy) { + effect(); + } + return effect; +} +function stop(effect) { + if (effect.active) { + cleanup(effect); + if (effect.options.onStop) { + effect.options.onStop(); + } + effect.active = false; + } +} +let uid = 0; +function createReactiveEffect(fn, options) { + const effect = function reactiveEffect() { + if (!effect.active) { + return options.scheduler ? undefined : fn(); + } + if (!effectStack.includes(effect)) { + cleanup(effect); + try { + enableTracking(); + effectStack.push(effect); + activeEffect = effect; + return fn(); + } + finally { + effectStack.pop(); + resetTracking(); + activeEffect = effectStack[effectStack.length - 1]; + } + } + }; + effect.id = uid++; + effect._isEffect = true; + effect.active = true; + effect.raw = fn; + effect.deps = []; + effect.options = options; + return effect; +} +function cleanup(effect) { + const { deps } = effect; + if (deps.length) { + for (let i = 0; i < deps.length; i++) { + deps[i].delete(effect); + } + deps.length = 0; + } +} +let shouldTrack = true; +const trackStack = []; +function pauseTracking() { + trackStack.push(shouldTrack); + shouldTrack = false; +} +function enableTracking() { + trackStack.push(shouldTrack); + shouldTrack = true; +} +function resetTracking() { + const last = trackStack.pop(); + shouldTrack = last === undefined ? true : last; +} +function track(target, type, key) { + if (!shouldTrack || activeEffect === undefined) { + return; + } + let depsMap = targetMap.get(target); + if (!depsMap) { + targetMap.set(target, (depsMap = new Map())); + } + let dep = depsMap.get(key); + if (!dep) { + depsMap.set(key, (dep = new Set())); + } + if (!dep.has(activeEffect)) { + dep.add(activeEffect); + activeEffect.deps.push(dep); + if ((process.env.NODE_ENV !== 'production') && activeEffect.options.onTrack) { + activeEffect.options.onTrack({ + effect: activeEffect, + target, + type, + key + }); + } + } +} +function trigger(target, type, key, newValue, oldValue, oldTarget) { + const depsMap = targetMap.get(target); + if (!depsMap) { + // never been tracked + return; + } + const effects = new Set(); + const add = (effectsToAdd) => { + if (effectsToAdd) { + effectsToAdd.forEach(effect => { + if (effect !== activeEffect || effect.options.allowRecurse) { + effects.add(effect); + } + }); + } + }; + if (type === "clear" /* CLEAR */) { + // collection being cleared + // trigger all effects for target + depsMap.forEach(add); + } + else if (key === 'length' && isArray(target)) { + depsMap.forEach((dep, key) => { + if (key === 'length' || key >= newValue) { + add(dep); + } + }); + } + else { + // schedule runs for SET | ADD | DELETE + if (key !== void 0) { + add(depsMap.get(key)); + } + // also run for iteration key on ADD | DELETE | Map.SET + switch (type) { + case "add" /* ADD */: + if (!isArray(target)) { + add(depsMap.get(ITERATE_KEY)); + if (isMap(target)) { + add(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } + else if (isIntegerKey(key)) { + // new index added to array -> length changes + add(depsMap.get('length')); + } + break; + case "delete" /* DELETE */: + if (!isArray(target)) { + add(depsMap.get(ITERATE_KEY)); + if (isMap(target)) { + add(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } + break; + case "set" /* SET */: + if (isMap(target)) { + add(depsMap.get(ITERATE_KEY)); + } + break; + } + } + const run = (effect) => { + if ((process.env.NODE_ENV !== 'production') && effect.options.onTrigger) { + effect.options.onTrigger({ + effect, + target, + key, + type, + newValue, + oldValue, + oldTarget + }); + } + if (effect.options.scheduler) { + effect.options.scheduler(effect); + } + else { + effect(); + } + }; + effects.forEach(run); } -const builtInSymbols = new Set( - Object.getOwnPropertyNames(Symbol) - .map(key => Symbol[key]) - .filter(isSymbol) -); -const get = /*#__PURE__*/ createGetter(); -const shallowGet = /*#__PURE__*/ createGetter(false, true); -const readonlyGet = /*#__PURE__*/ createGetter(true); -const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true); -const arrayInstrumentations = {} -;['includes', 'indexOf', 'lastIndexOf'].forEach(key => { - arrayInstrumentations[key] = function(...args) { - const arr = toRaw(this); - for (let i = 0, l = this.length; i < l; i++) { - track(arr, 'get' /* GET */, i + ''); - } - // we run the method using the original args first (which may be reactive) - const res = arr[key](...args); - if (res === -1 || res === false) { - // if that didn't work, run it again using raw values. - return arr[key](...args.map(toRaw)) - } else { - return res - } - }; -}); -function createGetter(isReadonly = false, shallow = false) { - return function get(target, key, receiver) { - if (key === '__v_isReactive' /* IS_REACTIVE */) { - return !isReadonly - } else if (key === '__v_isReadonly' /* IS_READONLY */) { - return isReadonly - } else if ( - key === '__v_raw' /* RAW */ && - receiver === (isReadonly ? readonlyMap : reactiveMap).get(target) - ) { - return target - } - const targetIsArray = isArray(target); - if (targetIsArray && hasOwn(arrayInstrumentations, key)) { - return Reflect.get(arrayInstrumentations, key, receiver) - } - const res = Reflect.get(target, key, receiver); - const keyIsSymbol = isSymbol(key); - if ( - keyIsSymbol - ? builtInSymbols.has(key) - : key === `__proto__` || key === `__v_isRef` - ) { - return res - } - if (!isReadonly) { - track(target, 'get' /* GET */, key); - } - if (shallow) { - return res - } - if (isRef(res)) { - // ref unwrapping - does not apply for Array + integer key. - const shouldUnwrap = !targetIsArray || !isIntegerKey(key); - return shouldUnwrap ? res.value : res - } - if (isObject(res)) { - // Convert returned value into a proxy as well. we do the isObject check - // here to avoid invalid value warning. Also need to lazy access readonly - // and reactive here to avoid circular dependency. - return isReadonly ? readonly(res) : reactive(res) - } - return res - } -} -const set = /*#__PURE__*/ createSetter(); -const shallowSet = /*#__PURE__*/ createSetter(true); -function createSetter(shallow = false) { - return function set(target, key, value, receiver) { - const oldValue = target[key]; - if (!shallow) { - value = toRaw(value); - if (!isArray(target) && isRef(oldValue) && !isRef(value)) { - oldValue.value = value; - return true - } - } - const hadKey = - isArray(target) && isIntegerKey(key) - ? Number(key) < target.length - : hasOwn(target, key); - const result = Reflect.set(target, key, value, receiver); - // don't trigger if target is something up in the prototype chain of original - if (target === toRaw(receiver)) { - if (!hadKey) { - trigger(target, 'add' /* ADD */, key, value); - } else if (hasChanged(value, oldValue)) { - trigger(target, 'set' /* SET */, key, value, oldValue); - } - } - return result - } -} -function deleteProperty(target, key) { - const hadKey = hasOwn(target, key); - const oldValue = target[key]; - const result = Reflect.deleteProperty(target, key); - if (result && hadKey) { - trigger(target, 'delete' /* DELETE */, key, undefined, oldValue); - } - return result -} -function has(target, key) { - const result = Reflect.has(target, key); - if (!isSymbol(key) || !builtInSymbols.has(key)) { - track(target, 'has' /* HAS */, key); - } - return result -} -function ownKeys(target) { - track(target, 'iterate' /* ITERATE */, ITERATE_KEY); - return Reflect.ownKeys(target) -} -const mutableHandlers = { - get, - set, - deleteProperty, - has, - ownKeys -}; -const readonlyHandlers = { - get: readonlyGet, - set(target, key) { - if (process.env.NODE_ENV !== 'production') { - console.warn( - `Set operation on key "${String(key)}" failed: target is readonly.`, - target - ); - } - return true - }, - deleteProperty(target, key) { - if (process.env.NODE_ENV !== 'production') { - console.warn( - `Delete operation on key "${String(key)}" failed: target is readonly.`, - target - ); - } - return true - } -}; -const shallowReactiveHandlers = extend({}, mutableHandlers, { - get: shallowGet, - set: shallowSet -}); -// Props handlers are special in the sense that it should not unwrap top-level -// refs (in order to allow refs to be explicitly passed down), but should -// retain the reactivity of the normal readonly object. -const shallowReadonlyHandlers = extend({}, readonlyHandlers, { - get: shallowReadonlyGet +const builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol) + .map(key => Symbol[key]) + .filter(isSymbol)); +const get = /*#__PURE__*/ createGetter(); +const shallowGet = /*#__PURE__*/ createGetter(false, true); +const readonlyGet = /*#__PURE__*/ createGetter(true); +const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true); +const arrayInstrumentations = {}; +['includes', 'indexOf', 'lastIndexOf'].forEach(key => { + const method = Array.prototype[key]; + arrayInstrumentations[key] = function (...args) { + const arr = toRaw(this); + for (let i = 0, l = this.length; i < l; i++) { + track(arr, "get" /* GET */, i + ''); + } + // we run the method using the original args first (which may be reactive) + const res = method.apply(arr, args); + if (res === -1 || res === false) { + // if that didn't work, run it again using raw values. + return method.apply(arr, args.map(toRaw)); + } + else { + return res; + } + }; +}); +['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => { + const method = Array.prototype[key]; + arrayInstrumentations[key] = function (...args) { + pauseTracking(); + const res = method.apply(this, args); + enableTracking(); + return res; + }; +}); +function createGetter(isReadonly = false, shallow = false) { + return function get(target, key, receiver) { + if (key === "__v_isReactive" /* IS_REACTIVE */) { + return !isReadonly; + } + else if (key === "__v_isReadonly" /* IS_READONLY */) { + return isReadonly; + } + else if (key === "__v_raw" /* RAW */ && + receiver === (isReadonly ? readonlyMap : reactiveMap).get(target)) { + return target; + } + const targetIsArray = isArray(target); + if (targetIsArray && hasOwn(arrayInstrumentations, key)) { + return Reflect.get(arrayInstrumentations, key, receiver); + } + const res = Reflect.get(target, key, receiver); + const keyIsSymbol = isSymbol(key); + if (keyIsSymbol + ? builtInSymbols.has(key) + : key === `__proto__` || key === `__v_isRef`) { + return res; + } + if (!isReadonly) { + track(target, "get" /* GET */, key); + } + if (shallow) { + return res; + } + if (isRef(res)) { + // ref unwrapping - does not apply for Array + integer key. + const shouldUnwrap = !targetIsArray || !isIntegerKey(key); + return shouldUnwrap ? res.value : res; + } + if (isObject(res)) { + // Convert returned value into a proxy as well. we do the isObject check + // here to avoid invalid value warning. Also need to lazy access readonly + // and reactive here to avoid circular dependency. + return isReadonly ? readonly(res) : reactive(res); + } + return res; + }; +} +const set = /*#__PURE__*/ createSetter(); +const shallowSet = /*#__PURE__*/ createSetter(true); +function createSetter(shallow = false) { + return function set(target, key, value, receiver) { + const oldValue = target[key]; + if (!shallow) { + value = toRaw(value); + if (!isArray(target) && isRef(oldValue) && !isRef(value)) { + oldValue.value = value; + return true; + } + } + const hadKey = isArray(target) && isIntegerKey(key) + ? Number(key) < target.length + : hasOwn(target, key); + const result = Reflect.set(target, key, value, receiver); + // don't trigger if target is something up in the prototype chain of original + if (target === toRaw(receiver)) { + if (!hadKey) { + trigger(target, "add" /* ADD */, key, value); + } + else if (hasChanged(value, oldValue)) { + trigger(target, "set" /* SET */, key, value, oldValue); + } + } + return result; + }; +} +function deleteProperty(target, key) { + const hadKey = hasOwn(target, key); + const oldValue = target[key]; + const result = Reflect.deleteProperty(target, key); + if (result && hadKey) { + trigger(target, "delete" /* DELETE */, key, undefined, oldValue); + } + return result; +} +function has(target, key) { + const result = Reflect.has(target, key); + if (!isSymbol(key) || !builtInSymbols.has(key)) { + track(target, "has" /* HAS */, key); + } + return result; +} +function ownKeys(target) { + track(target, "iterate" /* ITERATE */, ITERATE_KEY); + return Reflect.ownKeys(target); +} +const mutableHandlers = { + get, + set, + deleteProperty, + has, + ownKeys +}; +const readonlyHandlers = { + get: readonlyGet, + set(target, key) { + if ((process.env.NODE_ENV !== 'production')) { + console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target); + } + return true; + }, + deleteProperty(target, key) { + if ((process.env.NODE_ENV !== 'production')) { + console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target); + } + return true; + } +}; +const shallowReactiveHandlers = extend({}, mutableHandlers, { + get: shallowGet, + set: shallowSet +}); +// Props handlers are special in the sense that it should not unwrap top-level +// refs (in order to allow refs to be explicitly passed down), but should +// retain the reactivity of the normal readonly object. +const shallowReadonlyHandlers = extend({}, readonlyHandlers, { + get: shallowReadonlyGet }); -const toReactive = value => (isObject(value) ? reactive(value) : value); -const toReadonly = value => (isObject(value) ? readonly(value) : value); -const toShallow = value => value; -const getProto = v => Reflect.getPrototypeOf(v); -function get$1(target, key, isReadonly = false, isShallow = false) { - // #1772: readonly(reactive(Map)) should return readonly + reactive version - // of the value - target = target['__v_raw' /* RAW */]; - const rawTarget = toRaw(target); - const rawKey = toRaw(key); - if (key !== rawKey) { - !isReadonly && track(rawTarget, 'get' /* GET */, key); - } - !isReadonly && track(rawTarget, 'get' /* GET */, rawKey); - const { has } = getProto(rawTarget); - const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive; - if (has.call(rawTarget, key)) { - return wrap(target.get(key)) - } else if (has.call(rawTarget, rawKey)) { - return wrap(target.get(rawKey)) - } -} -function has$1(key, isReadonly = false) { - const target = this['__v_raw' /* RAW */]; - const rawTarget = toRaw(target); - const rawKey = toRaw(key); - if (key !== rawKey) { - !isReadonly && track(rawTarget, 'has' /* HAS */, key); - } - !isReadonly && track(rawTarget, 'has' /* HAS */, rawKey); - return key === rawKey - ? target.has(key) - : target.has(key) || target.has(rawKey) -} -function size(target, isReadonly = false) { - target = target['__v_raw' /* RAW */]; - !isReadonly && track(toRaw(target), 'iterate' /* ITERATE */, ITERATE_KEY); - return Reflect.get(target, 'size', target) -} -function add(value) { - value = toRaw(value); - const target = toRaw(this); - const proto = getProto(target); - const hadKey = proto.has.call(target, value); - const result = proto.add.call(target, value); - if (!hadKey) { - trigger(target, 'add' /* ADD */, value, value); - } - return result -} -function set$1(key, value) { - value = toRaw(value); - const target = toRaw(this); - const { has, get, set } = getProto(target); - let hadKey = has.call(target, key); - if (!hadKey) { - key = toRaw(key); - hadKey = has.call(target, key); - } else if (process.env.NODE_ENV !== 'production') { - checkIdentityKeys(target, has, key); - } - const oldValue = get.call(target, key); - const result = set.call(target, key, value); - if (!hadKey) { - trigger(target, 'add' /* ADD */, key, value); - } else if (hasChanged(value, oldValue)) { - trigger(target, 'set' /* SET */, key, value, oldValue); - } - return result -} -function deleteEntry(key) { - const target = toRaw(this); - const { has, get, delete: del } = getProto(target); - let hadKey = has.call(target, key); - if (!hadKey) { - key = toRaw(key); - hadKey = has.call(target, key); - } else if (process.env.NODE_ENV !== 'production') { - checkIdentityKeys(target, has, key); - } - const oldValue = get ? get.call(target, key) : undefined; - // forward the operation before queueing reactions - const result = del.call(target, key); - if (hadKey) { - trigger(target, 'delete' /* DELETE */, key, undefined, oldValue); - } - return result -} -function clear() { - const target = toRaw(this); - const hadItems = target.size !== 0; - const oldTarget = - process.env.NODE_ENV !== 'production' - ? target instanceof Map - ? new Map(target) - : new Set(target) - : undefined; - // forward the operation before queueing reactions - const result = getProto(target).clear.call(target); - if (hadItems) { - trigger(target, 'clear' /* CLEAR */, undefined, undefined, oldTarget); - } - return result -} -function createForEach(isReadonly, isShallow) { - return function forEach(callback, thisArg) { - const observed = this; - const target = observed['__v_raw' /* RAW */]; - const rawTarget = toRaw(target); - const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive; - !isReadonly && track(rawTarget, 'iterate' /* ITERATE */, ITERATE_KEY); - return target.forEach((value, key) => { - // important: make sure the callback is - // 1. invoked with the reactive map as `this` and 3rd arg - // 2. the value received should be a corresponding reactive/readonly. - return callback.call(thisArg, wrap(value), wrap(key), observed) - }) - } -} -function createIterableMethod(method, isReadonly, isShallow) { - return function(...args) { - const target = this['__v_raw' /* RAW */]; - const rawTarget = toRaw(target); - const isMap = rawTarget instanceof Map; - const isPair = method === 'entries' || (method === Symbol.iterator && isMap); - const isKeyOnly = method === 'keys' && isMap; - const innerIterator = target[method](...args); - const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive; - !isReadonly && - track( - rawTarget, - 'iterate' /* ITERATE */, - isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY - ); - // return a wrapped iterator which returns observed versions of the - // values emitted from the real iterator - return { - // iterator protocol - next() { - const { value, done } = innerIterator.next(); - return done - ? { value, done } - : { - value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), - done - } - }, - // iterable protocol - [Symbol.iterator]() { - return this - } - } - } -} -function createReadonlyMethod(type) { - return function(...args) { - if (process.env.NODE_ENV !== 'production') { - const key = args[0] ? `on key "${args[0]}" ` : ``; - console.warn( - `${capitalize(type)} operation ${key}failed: target is readonly.`, - toRaw(this) - ); - } - return type === 'delete' /* DELETE */ ? false : this - } -} -const mutableInstrumentations = { - get(key) { - return get$1(this, key) - }, - get size() { - return size(this) - }, - has: has$1, - add, - set: set$1, - delete: deleteEntry, - clear, - forEach: createForEach(false, false) -}; -const shallowInstrumentations = { - get(key) { - return get$1(this, key, false, true) - }, - get size() { - return size(this) - }, - has: has$1, - add, - set: set$1, - delete: deleteEntry, - clear, - forEach: createForEach(false, true) -}; -const readonlyInstrumentations = { - get(key) { - return get$1(this, key, true) - }, - get size() { - return size(this, true) - }, - has(key) { - return has$1.call(this, key, true) - }, - add: createReadonlyMethod('add' /* ADD */), - set: createReadonlyMethod('set' /* SET */), - delete: createReadonlyMethod('delete' /* DELETE */), - clear: createReadonlyMethod('clear' /* CLEAR */), - forEach: createForEach(true, false) -}; -const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]; -iteratorMethods.forEach(method => { - mutableInstrumentations[method] = createIterableMethod(method, false, false); - readonlyInstrumentations[method] = createIterableMethod(method, true, false); - shallowInstrumentations[method] = createIterableMethod(method, false, true); -}); -function createInstrumentationGetter(isReadonly, shallow) { - const instrumentations = shallow - ? shallowInstrumentations - : isReadonly - ? readonlyInstrumentations - : mutableInstrumentations; - return (target, key, receiver) => { - if (key === '__v_isReactive' /* IS_REACTIVE */) { - return !isReadonly - } else if (key === '__v_isReadonly' /* IS_READONLY */) { - return isReadonly - } else if (key === '__v_raw' /* RAW */) { - return target - } - return Reflect.get( - hasOwn(instrumentations, key) && key in target - ? instrumentations - : target, - key, - receiver - ) - } -} -const mutableCollectionHandlers = { - get: createInstrumentationGetter(false, false) -}; -const shallowCollectionHandlers = { - get: createInstrumentationGetter(false, true) -}; -const readonlyCollectionHandlers = { - get: createInstrumentationGetter(true, false) -}; -function checkIdentityKeys(target, has, key) { - const rawKey = toRaw(key); - if (rawKey !== key && has.call(target, rawKey)) { - const type = toRawType(target); - console.warn( - `Reactive ${type} contains both the raw and reactive ` + - `versions of the same object${type === `Map` ? `as keys` : ``}, ` + - `which can lead to inconsistencies. ` + - `Avoid differentiating between the raw and reactive versions ` + - `of an object and only use the reactive version if possible.` - ); - } +const toReactive = (value) => isObject(value) ? reactive(value) : value; +const toReadonly = (value) => isObject(value) ? readonly(value) : value; +const toShallow = (value) => value; +const getProto = (v) => Reflect.getPrototypeOf(v); +function get$1(target, key, isReadonly = false, isShallow = false) { + // #1772: readonly(reactive(Map)) should return readonly + reactive version + // of the value + target = target["__v_raw" /* RAW */]; + const rawTarget = toRaw(target); + const rawKey = toRaw(key); + if (key !== rawKey) { + !isReadonly && track(rawTarget, "get" /* GET */, key); + } + !isReadonly && track(rawTarget, "get" /* GET */, rawKey); + const { has } = getProto(rawTarget); + const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive; + if (has.call(rawTarget, key)) { + return wrap(target.get(key)); + } + else if (has.call(rawTarget, rawKey)) { + return wrap(target.get(rawKey)); + } +} +function has$1(key, isReadonly = false) { + const target = this["__v_raw" /* RAW */]; + const rawTarget = toRaw(target); + const rawKey = toRaw(key); + if (key !== rawKey) { + !isReadonly && track(rawTarget, "has" /* HAS */, key); + } + !isReadonly && track(rawTarget, "has" /* HAS */, rawKey); + return key === rawKey + ? target.has(key) + : target.has(key) || target.has(rawKey); +} +function size(target, isReadonly = false) { + target = target["__v_raw" /* RAW */]; + !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY); + return Reflect.get(target, 'size', target); +} +function add(value) { + value = toRaw(value); + const target = toRaw(this); + const proto = getProto(target); + const hadKey = proto.has.call(target, value); + const result = target.add(value); + if (!hadKey) { + trigger(target, "add" /* ADD */, value, value); + } + return result; +} +function set$1(key, value) { + value = toRaw(value); + const target = toRaw(this); + const { has, get } = getProto(target); + let hadKey = has.call(target, key); + if (!hadKey) { + key = toRaw(key); + hadKey = has.call(target, key); + } + else if ((process.env.NODE_ENV !== 'production')) { + checkIdentityKeys(target, has, key); + } + const oldValue = get.call(target, key); + const result = target.set(key, value); + if (!hadKey) { + trigger(target, "add" /* ADD */, key, value); + } + else if (hasChanged(value, oldValue)) { + trigger(target, "set" /* SET */, key, value, oldValue); + } + return result; +} +function deleteEntry(key) { + const target = toRaw(this); + const { has, get } = getProto(target); + let hadKey = has.call(target, key); + if (!hadKey) { + key = toRaw(key); + hadKey = has.call(target, key); + } + else if ((process.env.NODE_ENV !== 'production')) { + checkIdentityKeys(target, has, key); + } + const oldValue = get ? get.call(target, key) : undefined; + // forward the operation before queueing reactions + const result = target.delete(key); + if (hadKey) { + trigger(target, "delete" /* DELETE */, key, undefined, oldValue); + } + return result; +} +function clear() { + const target = toRaw(this); + const hadItems = target.size !== 0; + const oldTarget = (process.env.NODE_ENV !== 'production') + ? isMap(target) + ? new Map(target) + : new Set(target) + : undefined; + // forward the operation before queueing reactions + const result = target.clear(); + if (hadItems) { + trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget); + } + return result; +} +function createForEach(isReadonly, isShallow) { + return function forEach(callback, thisArg) { + const observed = this; + const target = observed["__v_raw" /* RAW */]; + const rawTarget = toRaw(target); + const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive; + !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY); + return target.forEach((value, key) => { + // important: make sure the callback is + // 1. invoked with the reactive map as `this` and 3rd arg + // 2. the value received should be a corresponding reactive/readonly. + return callback.call(thisArg, wrap(value), wrap(key), observed); + }); + }; +} +function createIterableMethod(method, isReadonly, isShallow) { + return function (...args) { + const target = this["__v_raw" /* RAW */]; + const rawTarget = toRaw(target); + const targetIsMap = isMap(rawTarget); + const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap); + const isKeyOnly = method === 'keys' && targetIsMap; + const innerIterator = target[method](...args); + const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive; + !isReadonly && + track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY); + // return a wrapped iterator which returns observed versions of the + // values emitted from the real iterator + return { + // iterator protocol + next() { + const { value, done } = innerIterator.next(); + return done + ? { value, done } + : { + value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), + done + }; + }, + // iterable protocol + [Symbol.iterator]() { + return this; + } + }; + }; +} +function createReadonlyMethod(type) { + return function (...args) { + if ((process.env.NODE_ENV !== 'production')) { + const key = args[0] ? `on key "${args[0]}" ` : ``; + console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this)); + } + return type === "delete" /* DELETE */ ? false : this; + }; +} +const mutableInstrumentations = { + get(key) { + return get$1(this, key); + }, + get size() { + return size(this); + }, + has: has$1, + add, + set: set$1, + delete: deleteEntry, + clear, + forEach: createForEach(false, false) +}; +const shallowInstrumentations = { + get(key) { + return get$1(this, key, false, true); + }, + get size() { + return size(this); + }, + has: has$1, + add, + set: set$1, + delete: deleteEntry, + clear, + forEach: createForEach(false, true) +}; +const readonlyInstrumentations = { + get(key) { + return get$1(this, key, true); + }, + get size() { + return size(this, true); + }, + has(key) { + return has$1.call(this, key, true); + }, + add: createReadonlyMethod("add" /* ADD */), + set: createReadonlyMethod("set" /* SET */), + delete: createReadonlyMethod("delete" /* DELETE */), + clear: createReadonlyMethod("clear" /* CLEAR */), + forEach: createForEach(true, false) +}; +const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]; +iteratorMethods.forEach(method => { + mutableInstrumentations[method] = createIterableMethod(method, false, false); + readonlyInstrumentations[method] = createIterableMethod(method, true, false); + shallowInstrumentations[method] = createIterableMethod(method, false, true); +}); +function createInstrumentationGetter(isReadonly, shallow) { + const instrumentations = shallow + ? shallowInstrumentations + : isReadonly + ? readonlyInstrumentations + : mutableInstrumentations; + return (target, key, receiver) => { + if (key === "__v_isReactive" /* IS_REACTIVE */) { + return !isReadonly; + } + else if (key === "__v_isReadonly" /* IS_READONLY */) { + return isReadonly; + } + else if (key === "__v_raw" /* RAW */) { + return target; + } + return Reflect.get(hasOwn(instrumentations, key) && key in target + ? instrumentations + : target, key, receiver); + }; +} +const mutableCollectionHandlers = { + get: createInstrumentationGetter(false, false) +}; +const shallowCollectionHandlers = { + get: createInstrumentationGetter(false, true) +}; +const readonlyCollectionHandlers = { + get: createInstrumentationGetter(true, false) +}; +function checkIdentityKeys(target, has, key) { + const rawKey = toRaw(key); + if (rawKey !== key && has.call(target, rawKey)) { + const type = toRawType(target); + console.warn(`Reactive ${type} contains both the raw and reactive ` + + `versions of the same object${type === `Map` ? `as keys` : ``}, ` + + `which can lead to inconsistencies. ` + + `Avoid differentiating between the raw and reactive versions ` + + `of an object and only use the reactive version if possible.`); + } } -const reactiveMap = new WeakMap(); -const readonlyMap = new WeakMap(); -function targetTypeMap(rawType) { - switch (rawType) { - case 'Object': - case 'Array': - return 1 /* COMMON */ - case 'Map': - case 'Set': - case 'WeakMap': - case 'WeakSet': - return 2 /* COLLECTION */ - default: - return 0 /* INVALID */ - } -} -function getTargetType(value) { - return value['__v_skip' /* SKIP */] || !Object.isExtensible(value) - ? 0 /* INVALID */ - : targetTypeMap(toRawType(value)) -} -function reactive(target) { - // if trying to observe a readonly proxy, return the readonly version. - if (target && target['__v_isReadonly' /* IS_READONLY */]) { - return target - } - return createReactiveObject( - target, - false, - mutableHandlers, - mutableCollectionHandlers - ) -} -// Return a reactive-copy of the original object, where only the root level -// properties are reactive, and does NOT unwrap refs nor recursively convert -// returned properties. -function shallowReactive(target) { - return createReactiveObject( - target, - false, - shallowReactiveHandlers, - shallowCollectionHandlers - ) -} -function readonly(target) { - return createReactiveObject( - target, - true, - readonlyHandlers, - readonlyCollectionHandlers - ) -} -// Return a reactive-copy of the original object, where only the root level -// properties are readonly, and does NOT unwrap refs nor recursively convert -// returned properties. -// This is used for creating the props proxy object for stateful components. -function shallowReadonly(target) { - return createReactiveObject( - target, - true, - shallowReadonlyHandlers, - readonlyCollectionHandlers - ) -} -function createReactiveObject( - target, - isReadonly, - baseHandlers, - collectionHandlers -) { - if (!isObject(target)) { - if (process.env.NODE_ENV !== 'production') { - console.warn(`value cannot be made reactive: ${String(target)}`); - } - return target - } - // target is already a Proxy, return it. - // exception: calling readonly() on a reactive object - if ( - target['__v_raw' /* RAW */] && - !(isReadonly && target['__v_isReactive' /* IS_REACTIVE */]) - ) { - return target - } - // target already has corresponding Proxy - const proxyMap = isReadonly ? readonlyMap : reactiveMap; - const existingProxy = proxyMap.get(target); - if (existingProxy) { - return existingProxy - } - // only a whitelist of value types can be observed. - const targetType = getTargetType(target); - if (targetType === 0 /* INVALID */) { - return target - } - const proxy = new Proxy( - target, - targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers - ); - proxyMap.set(target, proxy); - return proxy -} -function isReactive(value) { - if (isReadonly(value)) { - return isReactive(value['__v_raw' /* RAW */]) - } - return !!(value && value['__v_isReactive' /* IS_REACTIVE */]) -} -function isReadonly(value) { - return !!(value && value['__v_isReadonly' /* IS_READONLY */]) -} -function isProxy(value) { - return isReactive(value) || isReadonly(value) -} -function toRaw(observed) { - return (observed && toRaw(observed['__v_raw' /* RAW */])) || observed -} -function markRaw(value) { - def(value, '__v_skip' /* SKIP */, true); - return value +const reactiveMap = new WeakMap(); +const readonlyMap = new WeakMap(); +function targetTypeMap(rawType) { + switch (rawType) { + case 'Object': + case 'Array': + return 1 /* COMMON */; + case 'Map': + case 'Set': + case 'WeakMap': + case 'WeakSet': + return 2 /* COLLECTION */; + default: + return 0 /* INVALID */; + } +} +function getTargetType(value) { + return value["__v_skip" /* SKIP */] || !Object.isExtensible(value) + ? 0 /* INVALID */ + : targetTypeMap(toRawType(value)); +} +function reactive(target) { + // if trying to observe a readonly proxy, return the readonly version. + if (target && target["__v_isReadonly" /* IS_READONLY */]) { + return target; + } + return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers); +} +// Return a reactive-copy of the original object, where only the root level +// properties are reactive, and does NOT unwrap refs nor recursively convert +// returned properties. +function shallowReactive(target) { + return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers); +} +function readonly(target) { + return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers); +} +// Return a reactive-copy of the original object, where only the root level +// properties are readonly, and does NOT unwrap refs nor recursively convert +// returned properties. +// This is used for creating the props proxy object for stateful components. +function shallowReadonly(target) { + return createReactiveObject(target, true, shallowReadonlyHandlers, readonlyCollectionHandlers); +} +function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers) { + if (!isObject(target)) { + if ((process.env.NODE_ENV !== 'production')) { + console.warn(`value cannot be made reactive: ${String(target)}`); + } + return target; + } + // target is already a Proxy, return it. + // exception: calling readonly() on a reactive object + if (target["__v_raw" /* RAW */] && + !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) { + return target; + } + // target already has corresponding Proxy + const proxyMap = isReadonly ? readonlyMap : reactiveMap; + const existingProxy = proxyMap.get(target); + if (existingProxy) { + return existingProxy; + } + // only a whitelist of value types can be observed. + const targetType = getTargetType(target); + if (targetType === 0 /* INVALID */) { + return target; + } + const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers); + proxyMap.set(target, proxy); + return proxy; +} +function isReactive(value) { + if (isReadonly(value)) { + return isReactive(value["__v_raw" /* RAW */]); + } + return !!(value && value["__v_isReactive" /* IS_REACTIVE */]); +} +function isReadonly(value) { + return !!(value && value["__v_isReadonly" /* IS_READONLY */]); +} +function isProxy(value) { + return isReactive(value) || isReadonly(value); +} +function toRaw(observed) { + return ((observed && toRaw(observed["__v_raw" /* RAW */])) || observed); +} +function markRaw(value) { + def(value, "__v_skip" /* SKIP */, true); + return value; } -const convert = val => (isObject(val) ? reactive(val) : val); -function isRef(r) { - return Boolean(r && r.__v_isRef === true) -} -function ref(value) { - return createRef(value) -} -function shallowRef(value) { - return createRef(value, true) -} -class RefImpl { - constructor(_rawValue, _shallow = false) { - this._rawValue = _rawValue; - this._shallow = _shallow; - this.__v_isRef = true; - this._value = _shallow ? _rawValue : convert(_rawValue); - } - get value() { - track(toRaw(this), 'get' /* GET */, 'value'); - return this._value - } - set value(newVal) { - if (hasChanged(toRaw(newVal), this._rawValue)) { - this._rawValue = newVal; - this._value = this._shallow ? newVal : convert(newVal); - trigger(toRaw(this), 'set' /* SET */, 'value', newVal); - } - } -} -function createRef(rawValue, shallow = false) { - if (isRef(rawValue)) { - return rawValue - } - return new RefImpl(rawValue, shallow) -} -function triggerRef(ref) { - trigger( - ref, - 'set' /* SET */, - 'value', - process.env.NODE_ENV !== 'production' ? ref.value : void 0 - ); -} -function unref(ref) { - return isRef(ref) ? ref.value : ref -} -const shallowUnwrapHandlers = { - get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)), - set: (target, key, value, receiver) => { - const oldValue = target[key]; - if (isRef(oldValue) && !isRef(value)) { - oldValue.value = value; - return true - } else { - return Reflect.set(target, key, value, receiver) - } - } -}; -function proxyRefs(objectWithRefs) { - return isReactive(objectWithRefs) - ? objectWithRefs - : new Proxy(objectWithRefs, shallowUnwrapHandlers) -} -class CustomRefImpl { - constructor(factory) { - this.__v_isRef = true; - const { get, set } = factory( - () => track(this, 'get' /* GET */, 'value'), - () => trigger(this, 'set' /* SET */, 'value') - ); - this._get = get; - this._set = set; - } - get value() { - return this._get() - } - set value(newVal) { - this._set(newVal); - } -} -function customRef(factory) { - return new CustomRefImpl(factory) -} -function toRefs(object) { - if (process.env.NODE_ENV !== 'production' && !isProxy(object)) { - console.warn(`toRefs() expects a reactive object but received a plain one.`); - } - const ret = isArray(object) ? new Array(object.length) : {}; - for (const key in object) { - ret[key] = toRef(object, key); - } - return ret -} -class ObjectRefImpl { - constructor(_object, _key) { - this._object = _object; - this._key = _key; - this.__v_isRef = true; - } - get value() { - return this._object[this._key] - } - set value(newVal) { - this._object[this._key] = newVal; - } -} -function toRef(object, key) { - return new ObjectRefImpl(object, key) +const convert = (val) => isObject(val) ? reactive(val) : val; +function isRef(r) { + return Boolean(r && r.__v_isRef === true); +} +function ref(value) { + return createRef(value); +} +function shallowRef(value) { + return createRef(value, true); +} +class RefImpl { + constructor(_rawValue, _shallow = false) { + this._rawValue = _rawValue; + this._shallow = _shallow; + this.__v_isRef = true; + this._value = _shallow ? _rawValue : convert(_rawValue); + } + get value() { + track(toRaw(this), "get" /* GET */, 'value'); + return this._value; + } + set value(newVal) { + if (hasChanged(toRaw(newVal), this._rawValue)) { + this._rawValue = newVal; + this._value = this._shallow ? newVal : convert(newVal); + trigger(toRaw(this), "set" /* SET */, 'value', newVal); + } + } +} +function createRef(rawValue, shallow = false) { + if (isRef(rawValue)) { + return rawValue; + } + return new RefImpl(rawValue, shallow); +} +function triggerRef(ref) { + trigger(ref, "set" /* SET */, 'value', (process.env.NODE_ENV !== 'production') ? ref.value : void 0); +} +function unref(ref) { + return isRef(ref) ? ref.value : ref; +} +const shallowUnwrapHandlers = { + get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)), + set: (target, key, value, receiver) => { + const oldValue = target[key]; + if (isRef(oldValue) && !isRef(value)) { + oldValue.value = value; + return true; + } + else { + return Reflect.set(target, key, value, receiver); + } + } +}; +function proxyRefs(objectWithRefs) { + return isReactive(objectWithRefs) + ? objectWithRefs + : new Proxy(objectWithRefs, shallowUnwrapHandlers); +} +class CustomRefImpl { + constructor(factory) { + this.__v_isRef = true; + const { get, set } = factory(() => track(this, "get" /* GET */, 'value'), () => trigger(this, "set" /* SET */, 'value')); + this._get = get; + this._set = set; + } + get value() { + return this._get(); + } + set value(newVal) { + this._set(newVal); + } +} +function customRef(factory) { + return new CustomRefImpl(factory); +} +function toRefs(object) { + if ((process.env.NODE_ENV !== 'production') && !isProxy(object)) { + console.warn(`toRefs() expects a reactive object but received a plain one.`); + } + const ret = isArray(object) ? new Array(object.length) : {}; + for (const key in object) { + ret[key] = toRef(object, key); + } + return ret; +} +class ObjectRefImpl { + constructor(_object, _key) { + this._object = _object; + this._key = _key; + this.__v_isRef = true; + } + get value() { + return this._object[this._key]; + } + set value(newVal) { + this._object[this._key] = newVal; + } +} +function toRef(object, key) { + return isRef(object[key]) + ? object[key] + : new ObjectRefImpl(object, key); } -class ComputedRefImpl { - constructor(getter, _setter, isReadonly) { - this._setter = _setter; - this._dirty = true; - this.__v_isRef = true; - this.effect = effect(getter, { - lazy: true, - scheduler: () => { - if (!this._dirty) { - this._dirty = true; - trigger(toRaw(this), 'set' /* SET */, 'value'); - } - } - }); - this['__v_isReadonly' /* IS_READONLY */] = isReadonly; - } - get value() { - if (this._dirty) { - this._value = this.effect(); - this._dirty = false; - } - track(toRaw(this), 'get' /* GET */, 'value'); - return this._value - } - set value(newValue) { - this._setter(newValue); - } -} -function computed(getterOrOptions) { - let getter; - let setter; - if (isFunction(getterOrOptions)) { - getter = getterOrOptions; - setter = - process.env.NODE_ENV !== 'production' - ? () => { - console.warn('Write operation failed: computed value is readonly'); - } - : NOOP; - } else { - getter = getterOrOptions.get; - setter = getterOrOptions.set; - } - return new ComputedRefImpl( - getter, - setter, - isFunction(getterOrOptions) || !getterOrOptions.set - ) +class ComputedRefImpl { + constructor(getter, _setter, isReadonly) { + this._setter = _setter; + this._dirty = true; + this.__v_isRef = true; + this.effect = effect(getter, { + lazy: true, + scheduler: () => { + if (!this._dirty) { + this._dirty = true; + trigger(toRaw(this), "set" /* SET */, 'value'); + } + } + }); + this["__v_isReadonly" /* IS_READONLY */] = isReadonly; + } + get value() { + if (this._dirty) { + this._value = this.effect(); + this._dirty = false; + } + track(toRaw(this), "get" /* GET */, 'value'); + return this._value; + } + set value(newValue) { + this._setter(newValue); + } +} +function computed(getterOrOptions) { + let getter; + let setter; + if (isFunction(getterOrOptions)) { + getter = getterOrOptions; + setter = (process.env.NODE_ENV !== 'production') + ? () => { + console.warn('Write operation failed: computed value is readonly'); + } + : NOOP; + } + else { + getter = getterOrOptions.get; + setter = getterOrOptions.set; + } + return new ComputedRefImpl(getter, setter, isFunction(getterOrOptions) || !getterOrOptions.set); } -const stack = []; -function pushWarningContext(vnode) { - stack.push(vnode); -} -function popWarningContext() { - stack.pop(); -} -function warn(msg, ...args) { - // avoid props formatting or warn handler tracking deps that might be mutated - // during patch, leading to infinite recursion. - pauseTracking(); - const instance = stack.length ? stack[stack.length - 1].component : null; - const appWarnHandler = instance && instance.appContext.config.warnHandler; - const trace = getComponentTrace(); - if (appWarnHandler) { - callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [ - msg + args.join(''), - instance && instance.proxy, - trace - .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`) - .join('\n'), - trace - ]); - } else { - const warnArgs = [`[Vue warn]: ${msg}`, ...args]; - /* istanbul ignore if */ - if ( - trace.length && - // avoid spamming console during tests - !false - ) { - warnArgs.push(`\n`, ...formatTrace(trace)); - } - console.warn(...warnArgs); - } - resetTracking(); -} -function getComponentTrace() { - let currentVNode = stack[stack.length - 1]; - if (!currentVNode) { - return [] - } - // we can't just use the stack because it will be incomplete during updates - // that did not start from the root. Re-construct the parent chain using - // instance parent pointers. - const normalizedStack = []; - while (currentVNode) { - const last = normalizedStack[0]; - if (last && last.vnode === currentVNode) { - last.recurseCount++; - } else { - normalizedStack.push({ - vnode: currentVNode, - recurseCount: 0 - }); - } - const parentInstance = - currentVNode.component && currentVNode.component.parent; - currentVNode = parentInstance && parentInstance.vnode; - } - return normalizedStack -} -/* istanbul ignore next */ -function formatTrace(trace) { - const logs = []; - trace.forEach((entry, i) => { - logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry)); - }); - return logs -} -function formatTraceEntry({ vnode, recurseCount }) { - const postfix = - recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``; - const isRoot = vnode.component ? vnode.component.parent == null : false; - const open = ` at <${formatComponentName( - vnode.component, - vnode.type, - isRoot - )}`; - const close = `>` + postfix; - return vnode.props - ? [open, ...formatProps(vnode.props), close] - : [open + close] -} -/* istanbul ignore next */ -function formatProps(props) { - const res = []; - const keys = Object.keys(props); - keys.slice(0, 3).forEach(key => { - res.push(...formatProp(key, props[key])); - }); - if (keys.length > 3) { - res.push(` ...`); - } - return res -} -/* istanbul ignore next */ -function formatProp(key, value, raw) { - if (isString(value)) { - value = JSON.stringify(value); - return raw ? value : [`${key}=${value}`] - } else if ( - typeof value === 'number' || - typeof value === 'boolean' || - value == null - ) { - return raw ? value : [`${key}=${value}`] - } else if (isRef(value)) { - value = formatProp(key, toRaw(value.value), true); - return raw ? value : [`${key}=Ref<`, value, `>`] - } else if (isFunction(value)) { - return [`${key}=fn${value.name ? `<${value.name}>` : ``}`] - } else { - value = toRaw(value); - return raw ? value : [`${key}=`, value] - } +const stack = []; +function pushWarningContext(vnode) { + stack.push(vnode); +} +function popWarningContext() { + stack.pop(); +} +function warn(msg, ...args) { + // avoid props formatting or warn handler tracking deps that might be mutated + // during patch, leading to infinite recursion. + pauseTracking(); + const instance = stack.length ? stack[stack.length - 1].component : null; + const appWarnHandler = instance && instance.appContext.config.warnHandler; + const trace = getComponentTrace(); + if (appWarnHandler) { + callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [ + msg + args.join(''), + instance && instance.proxy, + trace + .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`) + .join('\n'), + trace + ]); + } + else { + const warnArgs = [`[Vue warn]: ${msg}`, ...args]; + /* istanbul ignore if */ + if (trace.length && + // avoid spamming console during tests + !false) { + warnArgs.push(`\n`, ...formatTrace(trace)); + } + console.warn(...warnArgs); + } + resetTracking(); +} +function getComponentTrace() { + let currentVNode = stack[stack.length - 1]; + if (!currentVNode) { + return []; + } + // we can't just use the stack because it will be incomplete during updates + // that did not start from the root. Re-construct the parent chain using + // instance parent pointers. + const normalizedStack = []; + while (currentVNode) { + const last = normalizedStack[0]; + if (last && last.vnode === currentVNode) { + last.recurseCount++; + } + else { + normalizedStack.push({ + vnode: currentVNode, + recurseCount: 0 + }); + } + const parentInstance = currentVNode.component && currentVNode.component.parent; + currentVNode = parentInstance && parentInstance.vnode; + } + return normalizedStack; +} +/* istanbul ignore next */ +function formatTrace(trace) { + const logs = []; + trace.forEach((entry, i) => { + logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry)); + }); + return logs; +} +function formatTraceEntry({ vnode, recurseCount }) { + const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``; + const isRoot = vnode.component ? vnode.component.parent == null : false; + const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`; + const close = `>` + postfix; + return vnode.props + ? [open, ...formatProps(vnode.props), close] + : [open + close]; +} +/* istanbul ignore next */ +function formatProps(props) { + const res = []; + const keys = Object.keys(props); + keys.slice(0, 3).forEach(key => { + res.push(...formatProp(key, props[key])); + }); + if (keys.length > 3) { + res.push(` ...`); + } + return res; +} +/* istanbul ignore next */ +function formatProp(key, value, raw) { + if (isString(value)) { + value = JSON.stringify(value); + return raw ? value : [`${key}=${value}`]; + } + else if (typeof value === 'number' || + typeof value === 'boolean' || + value == null) { + return raw ? value : [`${key}=${value}`]; + } + else if (isRef(value)) { + value = formatProp(key, toRaw(value.value), true); + return raw ? value : [`${key}=Ref<`, value, `>`]; + } + else if (isFunction(value)) { + return [`${key}=fn${value.name ? `<${value.name}>` : ``}`]; + } + else { + value = toRaw(value); + return raw ? value : [`${key}=`, value]; + } } -const ErrorTypeStrings = { - ['bc' /* BEFORE_CREATE */]: 'beforeCreate hook', - ['c' /* CREATED */]: 'created hook', - ['bm' /* BEFORE_MOUNT */]: 'beforeMount hook', - ['m' /* MOUNTED */]: 'mounted hook', - ['bu' /* BEFORE_UPDATE */]: 'beforeUpdate hook', - ['u' /* UPDATED */]: 'updated', - ['bum' /* BEFORE_UNMOUNT */]: 'beforeUnmount hook', - ['um' /* UNMOUNTED */]: 'unmounted hook', - ['a' /* ACTIVATED */]: 'activated hook', - ['da' /* DEACTIVATED */]: 'deactivated hook', - ['ec' /* ERROR_CAPTURED */]: 'errorCaptured hook', - ['rtc' /* RENDER_TRACKED */]: 'renderTracked hook', - ['rtg' /* RENDER_TRIGGERED */]: 'renderTriggered hook', - [0 /* SETUP_FUNCTION */]: 'setup function', - [1 /* RENDER_FUNCTION */]: 'render function', - [2 /* WATCH_GETTER */]: 'watcher getter', - [3 /* WATCH_CALLBACK */]: 'watcher callback', - [4 /* WATCH_CLEANUP */]: 'watcher cleanup function', - [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler', - [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler', - [7 /* VNODE_HOOK */]: 'vnode hook', - [8 /* DIRECTIVE_HOOK */]: 'directive hook', - [9 /* TRANSITION_HOOK */]: 'transition hook', - [10 /* APP_ERROR_HANDLER */]: 'app errorHandler', - [11 /* APP_WARN_HANDLER */]: 'app warnHandler', - [12 /* FUNCTION_REF */]: 'ref function', - [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader', - [14 /* SCHEDULER */]: - 'scheduler flush. This is likely a Vue internals bug. ' + - 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next' -}; -function callWithErrorHandling(fn, instance, type, args) { - let res; - try { - res = args ? fn(...args) : fn(); - } catch (err) { - handleError(err, instance, type); - } - return res -} -function callWithAsyncErrorHandling(fn, instance, type, args) { - if (isFunction(fn)) { - const res = callWithErrorHandling(fn, instance, type, args); - if (res && isPromise(res)) { - res.catch(err => { - handleError(err, instance, type); - }); - } - return res - } - const values = []; - for (let i = 0; i < fn.length; i++) { - values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)); - } - return values -} -function handleError(err, instance, type) { - const contextVNode = instance ? instance.vnode : null; - if (instance) { - let cur = instance.parent; - // the exposed instance is the render proxy to keep it consistent with 2.x - const exposedInstance = instance.proxy; - // in production the hook receives only the error code - const errorInfo = - process.env.NODE_ENV !== 'production' ? ErrorTypeStrings[type] : type; - while (cur) { - const errorCapturedHooks = cur.ec; - if (errorCapturedHooks) { - for (let i = 0; i < errorCapturedHooks.length; i++) { - if (errorCapturedHooks[i](err, exposedInstance, errorInfo)) { - return - } - } - } - cur = cur.parent; - } - // app-level handling - const appErrorHandler = instance.appContext.config.errorHandler; - if (appErrorHandler) { - callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [ - err, - exposedInstance, - errorInfo - ]); - return - } - } - logError(err, type, contextVNode); -} -function logError(err, type, contextVNode) { - if (process.env.NODE_ENV !== 'production') { - const info = ErrorTypeStrings[type]; - if (contextVNode) { - pushWarningContext(contextVNode); - } - warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`); - if (contextVNode) { - popWarningContext(); - } - // crash in dev so it's more noticeable - throw err - } else { - // recover in prod to reduce the impact on end-user - console.error(err); - } +const ErrorTypeStrings = { + ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook', + ["c" /* CREATED */]: 'created hook', + ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook', + ["m" /* MOUNTED */]: 'mounted hook', + ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook', + ["u" /* UPDATED */]: 'updated', + ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook', + ["um" /* UNMOUNTED */]: 'unmounted hook', + ["a" /* ACTIVATED */]: 'activated hook', + ["da" /* DEACTIVATED */]: 'deactivated hook', + ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook', + ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook', + ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook', + [0 /* SETUP_FUNCTION */]: 'setup function', + [1 /* RENDER_FUNCTION */]: 'render function', + [2 /* WATCH_GETTER */]: 'watcher getter', + [3 /* WATCH_CALLBACK */]: 'watcher callback', + [4 /* WATCH_CLEANUP */]: 'watcher cleanup function', + [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler', + [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler', + [7 /* VNODE_HOOK */]: 'vnode hook', + [8 /* DIRECTIVE_HOOK */]: 'directive hook', + [9 /* TRANSITION_HOOK */]: 'transition hook', + [10 /* APP_ERROR_HANDLER */]: 'app errorHandler', + [11 /* APP_WARN_HANDLER */]: 'app warnHandler', + [12 /* FUNCTION_REF */]: 'ref function', + [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader', + [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' + + 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next' +}; +function callWithErrorHandling(fn, instance, type, args) { + let res; + try { + res = args ? fn(...args) : fn(); + } + catch (err) { + handleError(err, instance, type); + } + return res; +} +function callWithAsyncErrorHandling(fn, instance, type, args) { + if (isFunction(fn)) { + const res = callWithErrorHandling(fn, instance, type, args); + if (res && isPromise(res)) { + res.catch(err => { + handleError(err, instance, type); + }); + } + return res; + } + const values = []; + for (let i = 0; i < fn.length; i++) { + values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)); + } + return values; +} +function handleError(err, instance, type, throwInDev = true) { + const contextVNode = instance ? instance.vnode : null; + if (instance) { + let cur = instance.parent; + // the exposed instance is the render proxy to keep it consistent with 2.x + const exposedInstance = instance.proxy; + // in production the hook receives only the error code + const errorInfo = (process.env.NODE_ENV !== 'production') ? ErrorTypeStrings[type] : type; + while (cur) { + const errorCapturedHooks = cur.ec; + if (errorCapturedHooks) { + for (let i = 0; i < errorCapturedHooks.length; i++) { + if (errorCapturedHooks[i](err, exposedInstance, errorInfo)) { + return; + } + } + } + cur = cur.parent; + } + // app-level handling + const appErrorHandler = instance.appContext.config.errorHandler; + if (appErrorHandler) { + callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]); + return; + } + } + logError(err, type, contextVNode, throwInDev); +} +function logError(err, type, contextVNode, throwInDev = true) { + if ((process.env.NODE_ENV !== 'production')) { + const info = ErrorTypeStrings[type]; + if (contextVNode) { + pushWarningContext(contextVNode); + } + warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`); + if (contextVNode) { + popWarningContext(); + } + // crash in dev by default so it's more noticeable + if (throwInDev) { + throw err; + } + else { + console.error(err); + } + } + else { + // recover in prod to reduce the impact on end-user + console.error(err); + } } -let isFlushing = false; -let isFlushPending = false; -const queue = []; -let flushIndex = 0; -const pendingPreFlushCbs = []; -let activePreFlushCbs = null; -let preFlushIndex = 0; -const pendingPostFlushCbs = []; -let activePostFlushCbs = null; -let postFlushIndex = 0; -const resolvedPromise = Promise.resolve(); -let currentFlushPromise = null; -let currentPreFlushParentJob = null; -const RECURSION_LIMIT = 100; -function nextTick(fn) { - const p = currentFlushPromise || resolvedPromise; - return fn ? p.then(fn) : p -} -function queueJob(job) { - // the dedupe search uses the startIndex argument of Array.includes() - // by default the search index includes the current job that is being run - // so it cannot recursively trigger itself again. - // if the job is a watch() callback, the search will start with a +1 index to - // allow it recursively trigger itself - it is the user's responsibility to - // ensure it doesn't end up in an infinite loop. - if ( - (!queue.length || - !queue.includes( - job, - isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex - )) && - job !== currentPreFlushParentJob - ) { - queue.push(job); - queueFlush(); - } -} -function queueFlush() { - if (!isFlushing && !isFlushPending) { - isFlushPending = true; - currentFlushPromise = resolvedPromise.then(flushJobs); - } -} -function invalidateJob(job) { - const i = queue.indexOf(job); - if (i > -1) { - queue[i] = null; - } -} -function queueCb(cb, activeQueue, pendingQueue, index) { - if (!isArray(cb)) { - if ( - !activeQueue || - !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index) - ) { - pendingQueue.push(cb); - } - } else { - // if cb is an array, it is a component lifecycle hook which can only be - // triggered by a job, which is already deduped in the main queue, so - // we can skip duplicate check here to improve perf - pendingQueue.push(...cb); - } - queueFlush(); -} -function queuePreFlushCb(cb) { - queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex); -} -function queuePostFlushCb(cb) { - queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex); -} -function flushPreFlushCbs(seen, parentJob = null) { - if (pendingPreFlushCbs.length) { - currentPreFlushParentJob = parentJob; - activePreFlushCbs = [...new Set(pendingPreFlushCbs)]; - pendingPreFlushCbs.length = 0; - if (process.env.NODE_ENV !== 'production') { - seen = seen || new Map(); - } - for ( - preFlushIndex = 0; - preFlushIndex < activePreFlushCbs.length; - preFlushIndex++ - ) { - if (process.env.NODE_ENV !== 'production') { - checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex]); - } - activePreFlushCbs[preFlushIndex](); - } - activePreFlushCbs = null; - preFlushIndex = 0; - currentPreFlushParentJob = null; - // recursively flush until it drains - flushPreFlushCbs(seen, parentJob); - } -} -function flushPostFlushCbs(seen) { - if (pendingPostFlushCbs.length) { - const deduped = [...new Set(pendingPostFlushCbs)]; - pendingPostFlushCbs.length = 0; - // #1947 already has active queue, nested flushPostFlushCbs call - if (activePostFlushCbs) { - activePostFlushCbs.push(...deduped); - return - } - activePostFlushCbs = deduped; - if (process.env.NODE_ENV !== 'production') { - seen = seen || new Map(); - } - activePostFlushCbs.sort((a, b) => getId(a) - getId(b)); - for ( - postFlushIndex = 0; - postFlushIndex < activePostFlushCbs.length; - postFlushIndex++ - ) { - if (process.env.NODE_ENV !== 'production') { - checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex]); - } - activePostFlushCbs[postFlushIndex](); - } - activePostFlushCbs = null; - postFlushIndex = 0; - } -} -const getId = job => (job.id == null ? Infinity : job.id); -function flushJobs(seen) { - isFlushPending = false; - isFlushing = true; - if (process.env.NODE_ENV !== 'production') { - seen = seen || new Map(); - } - flushPreFlushCbs(seen); - // Sort queue before flush. - // This ensures that: - // 1. Components are updated from parent to child. (because parent is always - // created before the child so its render effect will have smaller - // priority number) - // 2. If a component is unmounted during a parent component's update, - // its update can be skipped. - // Jobs can never be null before flush starts, since they are only invalidated - // during execution of another flushed job. - queue.sort((a, b) => getId(a) - getId(b)); - try { - for (flushIndex = 0; flushIndex < queue.length; flushIndex++) { - const job = queue[flushIndex]; - if (job) { - if (process.env.NODE_ENV !== 'production') { - checkRecursiveUpdates(seen, job); - } - callWithErrorHandling(job, null, 14 /* SCHEDULER */); - } - } - } finally { - flushIndex = 0; - queue.length = 0; - flushPostFlushCbs(seen); - isFlushing = false; - currentFlushPromise = null; - // some postFlushCb queued jobs! - // keep flushing until it drains. - if (queue.length || pendingPostFlushCbs.length) { - flushJobs(seen); - } - } -} -function checkRecursiveUpdates(seen, fn) { - if (!seen.has(fn)) { - seen.set(fn, 1); - } else { - const count = seen.get(fn); - if (count > RECURSION_LIMIT) { - throw new Error( - `Maximum recursive updates exceeded. ` + - `This means you have a reactive effect that is mutating its own ` + - `dependencies and thus recursively triggering itself. Possible sources ` + - `include component template, render function, updated hook or ` + - `watcher source function.` - ) - } else { - seen.set(fn, count + 1); - } - } +let isFlushing = false; +let isFlushPending = false; +const queue = []; +let flushIndex = 0; +const pendingPreFlushCbs = []; +let activePreFlushCbs = null; +let preFlushIndex = 0; +const pendingPostFlushCbs = []; +let activePostFlushCbs = null; +let postFlushIndex = 0; +const resolvedPromise = Promise.resolve(); +let currentFlushPromise = null; +let currentPreFlushParentJob = null; +const RECURSION_LIMIT = 100; +function nextTick(fn) { + const p = currentFlushPromise || resolvedPromise; + return fn ? p.then(fn) : p; +} +function queueJob(job) { + // the dedupe search uses the startIndex argument of Array.includes() + // by default the search index includes the current job that is being run + // so it cannot recursively trigger itself again. + // if the job is a watch() callback, the search will start with a +1 index to + // allow it recursively trigger itself - it is the user's responsibility to + // ensure it doesn't end up in an infinite loop. + if ((!queue.length || + !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) && + job !== currentPreFlushParentJob) { + queue.push(job); + queueFlush(); + } +} +function queueFlush() { + if (!isFlushing && !isFlushPending) { + isFlushPending = true; + currentFlushPromise = resolvedPromise.then(flushJobs); + } +} +function invalidateJob(job) { + const i = queue.indexOf(job); + if (i > -1) { + queue[i] = null; + } +} +function queueCb(cb, activeQueue, pendingQueue, index) { + if (!isArray(cb)) { + if (!activeQueue || + !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) { + pendingQueue.push(cb); + } + } + else { + // if cb is an array, it is a component lifecycle hook which can only be + // triggered by a job, which is already deduped in the main queue, so + // we can skip duplicate check here to improve perf + pendingQueue.push(...cb); + } + queueFlush(); +} +function queuePreFlushCb(cb) { + queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex); +} +function queuePostFlushCb(cb) { + queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex); +} +function flushPreFlushCbs(seen, parentJob = null) { + if (pendingPreFlushCbs.length) { + currentPreFlushParentJob = parentJob; + activePreFlushCbs = [...new Set(pendingPreFlushCbs)]; + pendingPreFlushCbs.length = 0; + if ((process.env.NODE_ENV !== 'production')) { + seen = seen || new Map(); + } + for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) { + if ((process.env.NODE_ENV !== 'production')) { + checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex]); + } + activePreFlushCbs[preFlushIndex](); + } + activePreFlushCbs = null; + preFlushIndex = 0; + currentPreFlushParentJob = null; + // recursively flush until it drains + flushPreFlushCbs(seen, parentJob); + } +} +function flushPostFlushCbs(seen) { + if (pendingPostFlushCbs.length) { + const deduped = [...new Set(pendingPostFlushCbs)]; + pendingPostFlushCbs.length = 0; + // #1947 already has active queue, nested flushPostFlushCbs call + if (activePostFlushCbs) { + activePostFlushCbs.push(...deduped); + return; + } + activePostFlushCbs = deduped; + if ((process.env.NODE_ENV !== 'production')) { + seen = seen || new Map(); + } + activePostFlushCbs.sort((a, b) => getId(a) - getId(b)); + for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) { + if ((process.env.NODE_ENV !== 'production')) { + checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex]); + } + activePostFlushCbs[postFlushIndex](); + } + activePostFlushCbs = null; + postFlushIndex = 0; + } +} +const getId = (job) => job.id == null ? Infinity : job.id; +function flushJobs(seen) { + isFlushPending = false; + isFlushing = true; + if ((process.env.NODE_ENV !== 'production')) { + seen = seen || new Map(); + } + flushPreFlushCbs(seen); + // Sort queue before flush. + // This ensures that: + // 1. Components are updated from parent to child. (because parent is always + // created before the child so its render effect will have smaller + // priority number) + // 2. If a component is unmounted during a parent component's update, + // its update can be skipped. + // Jobs can never be null before flush starts, since they are only invalidated + // during execution of another flushed job. + queue.sort((a, b) => getId(a) - getId(b)); + try { + for (flushIndex = 0; flushIndex < queue.length; flushIndex++) { + const job = queue[flushIndex]; + if (job) { + if ((process.env.NODE_ENV !== 'production')) { + checkRecursiveUpdates(seen, job); + } + callWithErrorHandling(job, null, 14 /* SCHEDULER */); + } + } + } + finally { + flushIndex = 0; + queue.length = 0; + flushPostFlushCbs(seen); + isFlushing = false; + currentFlushPromise = null; + // some postFlushCb queued jobs! + // keep flushing until it drains. + if (queue.length || pendingPostFlushCbs.length) { + flushJobs(seen); + } + } +} +function checkRecursiveUpdates(seen, fn) { + if (!seen.has(fn)) { + seen.set(fn, 1); + } + else { + const count = seen.get(fn); + if (count > RECURSION_LIMIT) { + throw new Error(`Maximum recursive updates exceeded. ` + + `This means you have a reactive effect that is mutating its own ` + + `dependencies and thus recursively triggering itself. Possible sources ` + + `include component template, render function, updated hook or ` + + `watcher source function.`); + } + else { + seen.set(fn, count + 1); + } + } } -let isHmrUpdating = false; -const hmrDirtyComponents = new Set(); -// Expose the HMR runtime on the global object -// This makes it entirely tree-shakable without polluting the exports and makes -// it easier to be used in toolings like vue-loader -// Note: for a component to be eligible for HMR it also needs the __hmrId option -// to be set so that its instances can be registered / removed. -if (process.env.NODE_ENV !== 'production') { - const globalObject = - typeof global !== 'undefined' - ? global - : typeof self !== 'undefined' - ? self - : typeof window !== 'undefined' - ? window - : {}; - globalObject.__VUE_HMR_RUNTIME__ = { - createRecord: tryWrap(createRecord), - rerender: tryWrap(rerender), - reload: tryWrap(reload) - }; -} -const map = new Map(); -function registerHMR(instance) { - const id = instance.type.__hmrId; - let record = map.get(id); - if (!record) { - createRecord(id); - record = map.get(id); - } - record.add(instance); -} -function unregisterHMR(instance) { - map.get(instance.type.__hmrId).delete(instance); -} -function createRecord(id) { - if (map.has(id)) { - return false - } - map.set(id, new Set()); - return true -} -function rerender(id, newRender) { - const record = map.get(id); - if (!record) return - // Array.from creates a snapshot which avoids the set being mutated during - // updates - Array.from(record).forEach(instance => { - if (newRender) { - instance.render = newRender; - } - instance.renderCache = []; - // this flag forces child components with slot content to update - isHmrUpdating = true; - instance.update(); - isHmrUpdating = false; - }); -} -function reload(id, newComp) { - const record = map.get(id); - if (!record) return - // Array.from creates a snapshot which avoids the set being mutated during - // updates - Array.from(record).forEach(instance => { - const comp = instance.type; - if (!hmrDirtyComponents.has(comp)) { - // 1. Update existing comp definition to match new one - extend(comp, newComp); - for (const key in comp) { - if (!(key in newComp)) { - delete comp[key]; - } - } - // 2. Mark component dirty. This forces the renderer to replace the component - // on patch. - hmrDirtyComponents.add(comp); - // 3. Make sure to unmark the component after the reload. - queuePostFlushCb(() => { - hmrDirtyComponents.delete(comp); - }); - } - if (instance.parent) { - // 4. Force the parent instance to re-render. This will cause all updated - // components to be unmounted and re-mounted. Queue the update so that we - // don't end up forcing the same parent to re-render multiple times. - queueJob(instance.parent.update); - } else if (instance.appContext.reload) { - // root instance mounted via createApp() has a reload method - instance.appContext.reload(); - } else if (typeof window !== 'undefined') { - // root instance inside tree created via raw render(). Force reload. - window.location.reload(); - } else { - console.warn( - '[HMR] Root or manually mounted instance modified. Full reload required.' - ); - } - }); -} -function tryWrap(fn) { - return (id, arg) => { - try { - return fn(id, arg) - } catch (e) { - console.error(e); - console.warn( - `[HMR] Something went wrong during Vue component hot-reload. ` + - `Full reload required.` - ); - } - } +/* eslint-disable no-restricted-globals */ +let isHmrUpdating = false; +const hmrDirtyComponents = new Set(); +// Expose the HMR runtime on the global object +// This makes it entirely tree-shakable without polluting the exports and makes +// it easier to be used in toolings like vue-loader +// Note: for a component to be eligible for HMR it also needs the __hmrId option +// to be set so that its instances can be registered / removed. +if ((process.env.NODE_ENV !== 'production')) { + const globalObject = typeof global !== 'undefined' + ? global + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : {}; + globalObject.__VUE_HMR_RUNTIME__ = { + createRecord: tryWrap(createRecord), + rerender: tryWrap(rerender), + reload: tryWrap(reload) + }; +} +const map = new Map(); +function registerHMR(instance) { + const id = instance.type.__hmrId; + let record = map.get(id); + if (!record) { + createRecord(id); + record = map.get(id); + } + record.add(instance); +} +function unregisterHMR(instance) { + map.get(instance.type.__hmrId).delete(instance); +} +function createRecord(id) { + if (map.has(id)) { + return false; + } + map.set(id, new Set()); + return true; +} +function rerender(id, newRender) { + const record = map.get(id); + if (!record) + return; + // Array.from creates a snapshot which avoids the set being mutated during + // updates + Array.from(record).forEach(instance => { + if (newRender) { + instance.render = newRender; + } + instance.renderCache = []; + // this flag forces child components with slot content to update + isHmrUpdating = true; + instance.update(); + isHmrUpdating = false; + }); +} +function reload(id, newComp) { + const record = map.get(id); + if (!record) + return; + // Array.from creates a snapshot which avoids the set being mutated during + // updates + Array.from(record).forEach(instance => { + const comp = instance.type; + if (!hmrDirtyComponents.has(comp)) { + // 1. Update existing comp definition to match new one + newComp = isClassComponent(newComp) ? newComp.__vccOpts : newComp; + extend(comp, newComp); + for (const key in comp) { + if (!(key in newComp)) { + delete comp[key]; + } + } + // 2. Mark component dirty. This forces the renderer to replace the component + // on patch. + hmrDirtyComponents.add(comp); + // 3. Make sure to unmark the component after the reload. + queuePostFlushCb(() => { + hmrDirtyComponents.delete(comp); + }); + } + if (instance.parent) { + // 4. Force the parent instance to re-render. This will cause all updated + // components to be unmounted and re-mounted. Queue the update so that we + // don't end up forcing the same parent to re-render multiple times. + queueJob(instance.parent.update); + } + else if (instance.appContext.reload) { + // root instance mounted via createApp() has a reload method + instance.appContext.reload(); + } + else if (typeof window !== 'undefined') { + // root instance inside tree created via raw render(). Force reload. + window.location.reload(); + } + else { + console.warn('[HMR] Root or manually mounted instance modified. Full reload required.'); + } + }); +} +function tryWrap(fn) { + return (id, arg) => { + try { + return fn(id, arg); + } + catch (e) { + console.error(e); + console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` + + `Full reload required.`); + } + }; } -// mark the current rendering instance for asset resolution (e.g. -// resolveComponent, resolveDirective) during render -let currentRenderingInstance = null; -function setCurrentRenderingInstance(instance) { - currentRenderingInstance = instance; -} -// dev only flag to track whether $attrs was used during render. -// If $attrs was used during render then the warning for failed attrs -// fallthrough can be suppressed. -let accessedAttrs = false; -function markAttrsAccessed() { - accessedAttrs = true; -} -function renderComponentRoot(instance) { - const { - type: Component, - vnode, - proxy, - withProxy, - props, - propsOptions: [propsOptions], - slots, - attrs, - emit, - render, - renderCache, - data, - setupState, - ctx - } = instance; - let result; - currentRenderingInstance = instance; - if (process.env.NODE_ENV !== 'production') { - accessedAttrs = false; - } - try { - let fallthroughAttrs; - if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) { - // withProxy is a proxy with a different `has` trap only for - // runtime-compiled render functions using `with` block. - const proxyToUse = withProxy || proxy; - result = normalizeVNode( - render.call( - proxyToUse, - proxyToUse, - renderCache, - props, - setupState, - data, - ctx - ) - ); - fallthroughAttrs = attrs; - } else { - // functional - const render = Component; - // in dev, mark attrs accessed if optional props (attrs === props) - if (process.env.NODE_ENV !== 'production' && attrs === props) { - markAttrsAccessed(); - } - result = normalizeVNode( - render.length > 1 - ? render( - props, - process.env.NODE_ENV !== 'production' - ? { - get attrs() { - markAttrsAccessed(); - return attrs - }, - slots, - emit - } - : { attrs, slots, emit } - ) - : render(props, null /* we know it doesn't need it */) - ); - fallthroughAttrs = Component.props - ? attrs - : getFunctionalFallthrough(attrs); - } - // attr merging - // in dev mode, comments are preserved, and it's possible for a template - // to have comments along side the root element which makes it a fragment - let root = result; - let setRoot = undefined; - if (process.env.NODE_ENV !== 'production') { - ;[root, setRoot] = getChildRoot(result); - } - if (Component.inheritAttrs !== false && fallthroughAttrs) { - const keys = Object.keys(fallthroughAttrs); - const { shapeFlag } = root; - if (keys.length) { - if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 6 /* COMPONENT */) { - if (propsOptions && keys.some(isModelListener)) { - // If a v-model listener (onUpdate:xxx) has a corresponding declared - // prop, it indicates this component expects to handle v-model and - // it should not fallthrough. - // related: #1543, #1643, #1989 - fallthroughAttrs = filterModelListeners( - fallthroughAttrs, - propsOptions - ); - } - root = cloneVNode(root, fallthroughAttrs); - } else if ( - process.env.NODE_ENV !== 'production' && - !accessedAttrs && - root.type !== Comment - ) { - const allAttrs = Object.keys(attrs); - const eventAttrs = []; - const extraAttrs = []; - for (let i = 0, l = allAttrs.length; i < l; i++) { - const key = allAttrs[i]; - if (isOn(key)) { - // ignore v-model handlers when they fail to fallthrough - if (!isModelListener(key)) { - // remove `on`, lowercase first letter to reflect event casing - // accurately - eventAttrs.push(key[2].toLowerCase() + key.slice(3)); - } - } else { - extraAttrs.push(key); - } - } - if (extraAttrs.length) { - warn( - `Extraneous non-props attributes (` + - `${extraAttrs.join(', ')}) ` + - `were passed to component but could not be automatically inherited ` + - `because component renders fragment or text root nodes.` - ); - } - if (eventAttrs.length) { - warn( - `Extraneous non-emits event listeners (` + - `${eventAttrs.join(', ')}) ` + - `were passed to component but could not be automatically inherited ` + - `because component renders fragment or text root nodes. ` + - `If the listener is intended to be a component custom event listener only, ` + - `declare it using the "emits" option.` - ); - } - } - } - } - // inherit directives - if (vnode.dirs) { - if (process.env.NODE_ENV !== 'production' && !isElementRoot(root)) { - warn( - `Runtime directive used on component with non-element root node. ` + - `The directives will not function as intended.` - ); - } - root.dirs = vnode.dirs; - } - // inherit transition data - if (vnode.transition) { - if (process.env.NODE_ENV !== 'production' && !isElementRoot(root)) { - warn( - `Component inside renders non-element root node ` + - `that cannot be animated.` - ); - } - root.transition = vnode.transition; - } - if (process.env.NODE_ENV !== 'production' && setRoot) { - setRoot(root); - } else { - result = root; - } - } catch (err) { - handleError(err, instance, 1 /* RENDER_FUNCTION */); - result = createVNode(Comment); - } - currentRenderingInstance = null; - return result -} -/** - * dev only - */ -const getChildRoot = vnode => { - if (vnode.type !== Fragment) { - return [vnode, undefined] - } - const rawChildren = vnode.children; - const dynamicChildren = vnode.dynamicChildren; - const children = rawChildren.filter(child => { - return !( - isVNode(child) && - child.type === Comment && - child.children !== 'v-if' - ) - }); - if (children.length !== 1) { - return [vnode, undefined] - } - const childRoot = children[0]; - const index = rawChildren.indexOf(childRoot); - const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1; - const setRoot = updatedRoot => { - rawChildren[index] = updatedRoot; - if (dynamicIndex > -1) { - dynamicChildren[dynamicIndex] = updatedRoot; - } else if (dynamicChildren && updatedRoot.patchFlag > 0) { - dynamicChildren.push(updatedRoot); - } - }; - return [normalizeVNode(childRoot), setRoot] -}; -const getFunctionalFallthrough = attrs => { - let res; - for (const key in attrs) { - if (key === 'class' || key === 'style' || isOn(key)) { -(res || (res = {}))[key] = attrs[key]; - } - } - return res -}; -const filterModelListeners = (attrs, props) => { - const res = {}; - for (const key in attrs) { - if (!isModelListener(key) || !(key.slice(9) in props)) { - res[key] = attrs[key]; - } - } - return res -}; -const isElementRoot = vnode => { - return ( - vnode.shapeFlag & 6 /* COMPONENT */ || - vnode.shapeFlag & 1 /* ELEMENT */ || - vnode.type === Comment // potential v-if branch switch - ) -}; -function shouldUpdateComponent(prevVNode, nextVNode, optimized) { - const { props: prevProps, children: prevChildren } = prevVNode; - const { props: nextProps, children: nextChildren, patchFlag } = nextVNode; - // Parent component's render function was hot-updated. Since this may have - // caused the child component's slots content to have changed, we need to - // force the child to update as well. - if ( - process.env.NODE_ENV !== 'production' && - (prevChildren || nextChildren) && - isHmrUpdating - ) { - return true - } - // force child update for runtime directive or transition on component vnode. - if (nextVNode.dirs || nextVNode.transition) { - return true - } - if (optimized && patchFlag > 0) { - if (patchFlag & 1024 /* DYNAMIC_SLOTS */) { - // slot content that references values that might have changed, - // e.g. in a v-for - return true - } - if (patchFlag & 16 /* FULL_PROPS */) { - if (!prevProps) { - return !!nextProps - } - // presence of this flag indicates props are always non-null - return hasPropsChanged(prevProps, nextProps) - } else if (patchFlag & 8 /* PROPS */) { - const dynamicProps = nextVNode.dynamicProps; - for (let i = 0; i < dynamicProps.length; i++) { - const key = dynamicProps[i]; - if (nextProps[key] !== prevProps[key]) { - return true - } - } - } - } else { - // this path is only taken by manually written render functions - // so presence of any children leads to a forced update - if (prevChildren || nextChildren) { - if (!nextChildren || !nextChildren.$stable) { - return true - } - } - if (prevProps === nextProps) { - return false - } - if (!prevProps) { - return !!nextProps - } - if (!nextProps) { - return true - } - return hasPropsChanged(prevProps, nextProps) - } - return false -} -function hasPropsChanged(prevProps, nextProps) { - const nextKeys = Object.keys(nextProps); - if (nextKeys.length !== Object.keys(prevProps).length) { - return true - } - for (let i = 0; i < nextKeys.length; i++) { - const key = nextKeys[i]; - if (nextProps[key] !== prevProps[key]) { - return true - } - } - return false -} -function updateHOCHostEl( - { vnode, parent }, - el // HostNode -) { - while (parent && parent.subTree === vnode) { -(vnode = parent.vnode).el = el; - parent = parent.parent; - } +let devtools; +function setDevtoolsHook(hook) { + devtools = hook; +} +function devtoolsInitApp(app, version) { + // TODO queue if devtools is undefined + if (!devtools) + return; + devtools.emit("app:init" /* APP_INIT */, app, version, { + Fragment, + Text, + Comment, + Static + }); +} +function devtoolsUnmountApp(app) { + if (!devtools) + return; + devtools.emit("app:unmount" /* APP_UNMOUNT */, app); +} +const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */); +const devtoolsComponentUpdated = /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */); +const devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */); +function createDevtoolsComponentHook(hook) { + return (component) => { + if (!devtools) + return; + devtools.emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined); + }; +} +function devtoolsComponentEmit(component, event, params) { + if (!devtools) + return; + devtools.emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params); } -const isSuspense = type => type.__isSuspense; -// Suspense exposes a component-like API, and is treated like a component -// in the compiler, but internally it's a special built-in type that hooks -// directly into the renderer. -const SuspenseImpl = { - // In order to make Suspense tree-shakable, we need to avoid importing it - // directly in the renderer. The renderer checks for the __isSuspense flag - // on a vnode's type and calls the `process` method, passing in renderer - // internals. - __isSuspense: true, - process( - n1, - n2, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized, - // platform-specific impl passed from renderer - rendererInternals - ) { - if (n1 == null) { - mountSuspense( - n2, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized, - rendererInternals - ); - } else { - patchSuspense( - n1, - n2, - container, - anchor, - parentComponent, - isSVG, - optimized, - rendererInternals - ); - } - }, - hydrate: hydrateSuspense -}; -// Force-casted public typing for h and TSX props inference -const Suspense = SuspenseImpl; -function mountSuspense( - n2, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized, - rendererInternals -) { - const { - p: patch, - o: { createElement } - } = rendererInternals; - const hiddenContainer = createElement('div'); - const suspense = (n2.suspense = createSuspenseBoundary( - n2, - parentSuspense, - parentComponent, - container, - hiddenContainer, - anchor, - isSVG, - optimized, - rendererInternals - )); - // start mounting the content subtree in an off-dom container - patch( - null, - suspense.subTree, - hiddenContainer, - null, - parentComponent, - suspense, - isSVG, - optimized - ); - // now check if we have encountered any async deps - if (suspense.deps > 0) { - // mount the fallback tree - patch( - null, - suspense.fallbackTree, - container, - anchor, - parentComponent, - null, // fallback tree will not have suspense context - isSVG, - optimized - ); - n2.el = suspense.fallbackTree.el; - } else { - // Suspense has no async deps. Just resolve. - suspense.resolve(); - } -} -function patchSuspense( - n1, - n2, - container, - anchor, - parentComponent, - isSVG, - optimized, - { p: patch } -) { - const suspense = (n2.suspense = n1.suspense); - suspense.vnode = n2; - const { content, fallback } = normalizeSuspenseChildren(n2); - const oldSubTree = suspense.subTree; - const oldFallbackTree = suspense.fallbackTree; - if (!suspense.isResolved) { - patch( - oldSubTree, - content, - suspense.hiddenContainer, - null, - parentComponent, - suspense, - isSVG, - optimized - ); - if (suspense.deps > 0) { - // still pending. patch the fallback tree. - patch( - oldFallbackTree, - fallback, - container, - anchor, - parentComponent, - null, // fallback tree will not have suspense context - isSVG, - optimized - ); - n2.el = fallback.el; - } - // If deps somehow becomes 0 after the patch it means the patch caused an - // async dep component to unmount and removed its dep. It will cause the - // suspense to resolve and we don't need to do anything here. - } else { - // just normal patch inner content as a fragment - patch( - oldSubTree, - content, - container, - anchor, - parentComponent, - suspense, - isSVG, - optimized - ); - n2.el = content.el; - } - suspense.subTree = content; - suspense.fallbackTree = fallback; -} -let hasWarned = false; -function createSuspenseBoundary( - vnode, - parent, - parentComponent, - container, - hiddenContainer, - anchor, - isSVG, - optimized, - rendererInternals, - isHydrating = false -) { - /* istanbul ignore if */ - if (process.env.NODE_ENV !== 'production' && !false && !hasWarned) { - hasWarned = true; - // @ts-ignore `console.info` cannot be null error - console[console.info ? 'info' : 'log']( - ` is an experimental feature and its API will likely change.` - ); - } - const { - p: patch, - m: move, - um: unmount, - n: next, - o: { parentNode } - } = rendererInternals; - const getCurrentTree = () => - suspense.isResolved || suspense.isHydrating - ? suspense.subTree - : suspense.fallbackTree; - const { content, fallback } = normalizeSuspenseChildren(vnode); - const suspense = { - vnode, - parent, - parentComponent, - isSVG, - optimized, - container, - hiddenContainer, - anchor, - deps: 0, - subTree: content, - fallbackTree: fallback, - isHydrating, - isResolved: false, - isUnmounted: false, - effects: [], - resolve() { - if (process.env.NODE_ENV !== 'production') { - if (suspense.isResolved) { - throw new Error( - `resolveSuspense() is called on an already resolved suspense boundary.` - ) - } - if (suspense.isUnmounted) { - throw new Error( - `resolveSuspense() is called on an already unmounted suspense boundary.` - ) - } - } - const { - vnode, - subTree, - fallbackTree, - effects, - parentComponent, - container - } = suspense; - if (suspense.isHydrating) { - suspense.isHydrating = false; - } else { - // this is initial anchor on mount - let { anchor } = suspense; - // unmount fallback tree - if (fallbackTree.el) { - // if the fallback tree was mounted, it may have been moved - // as part of a parent suspense. get the latest anchor for insertion - anchor = next(fallbackTree); - unmount(fallbackTree, parentComponent, suspense, true); - } - // move content from off-dom container to actual container - move(subTree, container, anchor, 0 /* ENTER */); - } - const el = (vnode.el = subTree.el); - // suspense as the root node of a component... - if (parentComponent && parentComponent.subTree === vnode) { - parentComponent.vnode.el = el; - updateHOCHostEl(parentComponent, el); - } - // check if there is a pending parent suspense - let parent = suspense.parent; - let hasUnresolvedAncestor = false; - while (parent) { - if (!parent.isResolved) { - // found a pending parent suspense, merge buffered post jobs - // into that parent - parent.effects.push(...effects); - hasUnresolvedAncestor = true; - break - } - parent = parent.parent; - } - // no pending parent suspense, flush all jobs - if (!hasUnresolvedAncestor) { - queuePostFlushCb(effects); - } - suspense.isResolved = true; - suspense.effects = []; - // invoke @resolve event - const onResolve = vnode.props && vnode.props.onResolve; - if (isFunction(onResolve)) { - onResolve(); - } - }, - recede() { - suspense.isResolved = false; - const { - vnode, - subTree, - fallbackTree, - parentComponent, - container, - hiddenContainer, - isSVG, - optimized - } = suspense; - // move content tree back to the off-dom container - const anchor = next(subTree); - move(subTree, hiddenContainer, null, 1 /* LEAVE */); - // remount the fallback tree - patch( - null, - fallbackTree, - container, - anchor, - parentComponent, - null, // fallback tree will not have suspense context - isSVG, - optimized - ); - const el = (vnode.el = fallbackTree.el); - // suspense as the root node of a component... - if (parentComponent && parentComponent.subTree === vnode) { - parentComponent.vnode.el = el; - updateHOCHostEl(parentComponent, el); - } - // invoke @recede event - const onRecede = vnode.props && vnode.props.onRecede; - if (isFunction(onRecede)) { - onRecede(); - } - }, - move(container, anchor, type) { - move(getCurrentTree(), container, anchor, type); - suspense.container = container; - }, - next() { - return next(getCurrentTree()) - }, - registerDep(instance, setupRenderEffect) { - // suspense is already resolved, need to recede. - // use queueJob so it's handled synchronously after patching the current - // suspense tree - if (suspense.isResolved) { - queueJob(() => { - suspense.recede(); - }); - } - const hydratedEl = instance.vnode.el; - suspense.deps++; - instance.asyncDep - .catch(err => { - handleError(err, instance, 0 /* SETUP_FUNCTION */); - }) - .then(asyncSetupResult => { - // retry when the setup() promise resolves. - // component may have been unmounted before resolve. - if (instance.isUnmounted || suspense.isUnmounted) { - return - } - suspense.deps--; - // retry from this component - instance.asyncResolved = true; - const { vnode } = instance; - if (process.env.NODE_ENV !== 'production') { - pushWarningContext(vnode); - } - handleSetupResult(instance, asyncSetupResult); - if (hydratedEl) { - // vnode may have been replaced if an update happened before the - // async dep is resolved. - vnode.el = hydratedEl; - } - setupRenderEffect( - instance, - vnode, - // component may have been moved before resolve. - // if this is not a hydration, instance.subTree will be the comment - // placeholder. - hydratedEl - ? parentNode(hydratedEl) - : parentNode(instance.subTree.el), - // anchor will not be used if this is hydration, so only need to - // consider the comment placeholder case. - hydratedEl ? null : next(instance.subTree), - suspense, - isSVG, - optimized - ); - updateHOCHostEl(instance, vnode.el); - if (process.env.NODE_ENV !== 'production') { - popWarningContext(); - } - if (suspense.deps === 0) { - suspense.resolve(); - } - }); - }, - unmount(parentSuspense, doRemove) { - suspense.isUnmounted = true; - unmount(suspense.subTree, parentComponent, parentSuspense, doRemove); - if (!suspense.isResolved) { - unmount( - suspense.fallbackTree, - parentComponent, - parentSuspense, - doRemove - ); - } - } - }; - return suspense -} -function hydrateSuspense( - node, - vnode, - parentComponent, - parentSuspense, - isSVG, - optimized, - rendererInternals, - hydrateNode -) { - /* eslint-disable no-restricted-globals */ - const suspense = (vnode.suspense = createSuspenseBoundary( - vnode, - parentSuspense, - parentComponent, - node.parentNode, - document.createElement('div'), - null, - isSVG, - optimized, - rendererInternals, - true /* hydrating */ - )); - // there are two possible scenarios for server-rendered suspense: - // - success: ssr content should be fully resolved - // - failure: ssr content should be the fallback branch. - // however, on the client we don't really know if it has failed or not - // attempt to hydrate the DOM assuming it has succeeded, but we still - // need to construct a suspense boundary first - const result = hydrateNode( - node, - suspense.subTree, - parentComponent, - suspense, - optimized - ); - if (suspense.deps === 0) { - suspense.resolve(); - } - return result - /* eslint-enable no-restricted-globals */ -} -function normalizeSuspenseChildren(vnode) { - const { shapeFlag, children } = vnode; - if (shapeFlag & 32 /* SLOTS_CHILDREN */) { - const { default: d, fallback } = children; - return { - content: normalizeVNode(isFunction(d) ? d() : d), - fallback: normalizeVNode(isFunction(fallback) ? fallback() : fallback) - } - } else { - return { - content: normalizeVNode(children), - fallback: normalizeVNode(null) - } - } -} -function queueEffectWithSuspense(fn, suspense) { - if (suspense && !suspense.isResolved) { - if (isArray(fn)) { - suspense.effects.push(...fn); - } else { - suspense.effects.push(fn); - } - } else { - queuePostFlushCb(fn); - } +function emit(instance, event, ...args) { + const props = instance.vnode.props || EMPTY_OBJ; + if ((process.env.NODE_ENV !== 'production')) { + const { emitsOptions, propsOptions: [propsOptions] } = instance; + if (emitsOptions) { + if (!(event in emitsOptions)) { + if (!propsOptions || !(`on` + capitalize(event) in propsOptions)) { + warn(`Component emitted event "${event}" but it is neither declared in ` + + `the emits option nor as an "on${capitalize(event)}" prop.`); + } + } + else { + const validator = emitsOptions[event]; + if (isFunction(validator)) { + const isValid = validator(...args); + if (!isValid) { + warn(`Invalid event arguments: event validation failed for event "${event}".`); + } + } + } + } + } + if ((process.env.NODE_ENV !== 'production') || __VUE_PROD_DEVTOOLS__) { + devtoolsComponentEmit(instance, event, args); + } + let handlerName = `on${capitalize(event)}`; + let handler = props[handlerName]; + // for v-model update:xxx events, also trigger kebab-case equivalent + // for props passed via kebab-case + if (!handler && event.startsWith('update:')) { + handlerName = `on${capitalize(hyphenate(event))}`; + handler = props[handlerName]; + } + if (!handler) { + handler = props[handlerName + `Once`]; + if (!instance.emitted) { + (instance.emitted = {})[handlerName] = true; + } + else if (instance.emitted[handlerName]) { + return; + } + } + if (handler) { + callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args); + } +} +function normalizeEmitsOptions(comp, appContext, asMixin = false) { + const appId = appContext.app ? appContext.app._uid : -1; + const cache = comp.__emits || (comp.__emits = {}); + const cached = cache[appId]; + if (cached !== undefined) { + return cached; + } + const raw = comp.emits; + let normalized = {}; + // apply mixin/extends props + let hasExtends = false; + if (__VUE_OPTIONS_API__ && !isFunction(comp)) { + const extendEmits = (raw) => { + hasExtends = true; + extend(normalized, normalizeEmitsOptions(raw, appContext, true)); + }; + if (!asMixin && appContext.mixins.length) { + appContext.mixins.forEach(extendEmits); + } + if (comp.extends) { + extendEmits(comp.extends); + } + if (comp.mixins) { + comp.mixins.forEach(extendEmits); + } + } + if (!raw && !hasExtends) { + return (cache[appId] = null); + } + if (isArray(raw)) { + raw.forEach(key => (normalized[key] = null)); + } + else { + extend(normalized, raw); + } + return (cache[appId] = normalized); +} +// Check if an incoming prop key is a declared emit event listener. +// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are +// both considered matched listeners. +function isEmitListener(options, key) { + if (!options || !isOn(key)) { + return false; + } + key = key.replace(/Once$/, ''); + return (hasOwn(options, key[2].toLowerCase() + key.slice(3)) || + hasOwn(options, key.slice(2))); } -let isRenderingCompiledSlot = 0; -const setCompiledSlotRendering = n => (isRenderingCompiledSlot += n); -/** - * Compiler runtime helper for rendering `` - * @private - */ -function renderSlot( - slots, - name, - props = {}, - // this is not a user-facing function, so the fallback is always generated by - // the compiler and guaranteed to be a function returning an array - fallback -) { - let slot = slots[name]; - if (process.env.NODE_ENV !== 'production' && slot && slot.length > 1) { - warn( - `SSR-optimized slot function detected in a non-SSR-optimized render ` + - `function. You need to mark this component with $dynamic-slots in the ` + - `parent template.` - ); - slot = () => []; - } - // a compiled slot disables block tracking by default to avoid manual - // invocation interfering with template-based block tracking, but in - // `renderSlot` we can be sure that it's template-based so we can force - // enable it. - isRenderingCompiledSlot++; - const rendered = (openBlock(), - createBlock( - Fragment, - { key: props.key }, - slot ? slot(props) : fallback ? fallback() : [], - slots._ === 1 /* STABLE */ ? 64 /* STABLE_FRAGMENT */ : -2 /* BAIL */ - )); - isRenderingCompiledSlot--; - return rendered +// mark the current rendering instance for asset resolution (e.g. +// resolveComponent, resolveDirective) during render +let currentRenderingInstance = null; +function setCurrentRenderingInstance(instance) { + currentRenderingInstance = instance; +} +// dev only flag to track whether $attrs was used during render. +// If $attrs was used during render then the warning for failed attrs +// fallthrough can be suppressed. +let accessedAttrs = false; +function markAttrsAccessed() { + accessedAttrs = true; +} +function renderComponentRoot(instance) { + const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx } = instance; + let result; + currentRenderingInstance = instance; + if ((process.env.NODE_ENV !== 'production')) { + accessedAttrs = false; + } + try { + let fallthroughAttrs; + if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) { + // withProxy is a proxy with a different `has` trap only for + // runtime-compiled render functions using `with` block. + const proxyToUse = withProxy || proxy; + result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx)); + fallthroughAttrs = attrs; + } + else { + // functional + const render = Component; + // in dev, mark attrs accessed if optional props (attrs === props) + if ((process.env.NODE_ENV !== 'production') && attrs === props) { + markAttrsAccessed(); + } + result = normalizeVNode(render.length > 1 + ? render(props, (process.env.NODE_ENV !== 'production') + ? { + get attrs() { + markAttrsAccessed(); + return attrs; + }, + slots, + emit + } + : { attrs, slots, emit }) + : render(props, null /* we know it doesn't need it */)); + fallthroughAttrs = Component.props + ? attrs + : getFunctionalFallthrough(attrs); + } + // attr merging + // in dev mode, comments are preserved, and it's possible for a template + // to have comments along side the root element which makes it a fragment + let root = result; + let setRoot = undefined; + if ((process.env.NODE_ENV !== 'production')) { + ; + [root, setRoot] = getChildRoot(result); + } + if (Component.inheritAttrs !== false && fallthroughAttrs) { + const keys = Object.keys(fallthroughAttrs); + const { shapeFlag } = root; + if (keys.length) { + if (shapeFlag & 1 /* ELEMENT */ || + shapeFlag & 6 /* COMPONENT */) { + if (propsOptions && keys.some(isModelListener)) { + // If a v-model listener (onUpdate:xxx) has a corresponding declared + // prop, it indicates this component expects to handle v-model and + // it should not fallthrough. + // related: #1543, #1643, #1989 + fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions); + } + root = cloneVNode(root, fallthroughAttrs); + } + else if ((process.env.NODE_ENV !== 'production') && !accessedAttrs && root.type !== Comment) { + const allAttrs = Object.keys(attrs); + const eventAttrs = []; + const extraAttrs = []; + for (let i = 0, l = allAttrs.length; i < l; i++) { + const key = allAttrs[i]; + if (isOn(key)) { + // ignore v-model handlers when they fail to fallthrough + if (!isModelListener(key)) { + // remove `on`, lowercase first letter to reflect event casing + // accurately + eventAttrs.push(key[2].toLowerCase() + key.slice(3)); + } + } + else { + extraAttrs.push(key); + } + } + if (extraAttrs.length) { + warn(`Extraneous non-props attributes (` + + `${extraAttrs.join(', ')}) ` + + `were passed to component but could not be automatically inherited ` + + `because component renders fragment or text root nodes.`); + } + if (eventAttrs.length) { + warn(`Extraneous non-emits event listeners (` + + `${eventAttrs.join(', ')}) ` + + `were passed to component but could not be automatically inherited ` + + `because component renders fragment or text root nodes. ` + + `If the listener is intended to be a component custom event listener only, ` + + `declare it using the "emits" option.`); + } + } + } + } + // inherit directives + if (vnode.dirs) { + if ((process.env.NODE_ENV !== 'production') && !isElementRoot(root)) { + warn(`Runtime directive used on component with non-element root node. ` + + `The directives will not function as intended.`); + } + root.dirs = vnode.dirs; + } + // inherit transition data + if (vnode.transition) { + if ((process.env.NODE_ENV !== 'production') && !isElementRoot(root)) { + warn(`Component inside renders non-element root node ` + + `that cannot be animated.`); + } + root.transition = vnode.transition; + } + if ((process.env.NODE_ENV !== 'production') && setRoot) { + setRoot(root); + } + else { + result = root; + } + } + catch (err) { + handleError(err, instance, 1 /* RENDER_FUNCTION */); + result = createVNode(Comment); + } + currentRenderingInstance = null; + return result; +} +/** + * dev only + * In dev mode, template root level comments are rendered, which turns the + * template into a fragment root, but we need to locate the single element + * root for attrs and scope id processing. + */ +const getChildRoot = (vnode) => { + if (vnode.type !== Fragment) { + return [vnode, undefined]; + } + const rawChildren = vnode.children; + const dynamicChildren = vnode.dynamicChildren; + const childRoot = filterSingleRoot(rawChildren); + if (!childRoot) { + return [vnode, undefined]; + } + const index = rawChildren.indexOf(childRoot); + const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1; + const setRoot = (updatedRoot) => { + rawChildren[index] = updatedRoot; + if (dynamicIndex > -1) { + dynamicChildren[dynamicIndex] = updatedRoot; + } + else if (dynamicChildren && updatedRoot.patchFlag > 0) { + dynamicChildren.push(updatedRoot); + } + }; + return [normalizeVNode(childRoot), setRoot]; +}; +/** + * dev only + */ +function filterSingleRoot(children) { + const filtered = children.filter(child => { + return !(isVNode(child) && + child.type === Comment && + child.children !== 'v-if'); + }); + return filtered.length === 1 && isVNode(filtered[0]) ? filtered[0] : null; +} +const getFunctionalFallthrough = (attrs) => { + let res; + for (const key in attrs) { + if (key === 'class' || key === 'style' || isOn(key)) { + (res || (res = {}))[key] = attrs[key]; + } + } + return res; +}; +const filterModelListeners = (attrs, props) => { + const res = {}; + for (const key in attrs) { + if (!isModelListener(key) || !(key.slice(9) in props)) { + res[key] = attrs[key]; + } + } + return res; +}; +const isElementRoot = (vnode) => { + return (vnode.shapeFlag & 6 /* COMPONENT */ || + vnode.shapeFlag & 1 /* ELEMENT */ || + vnode.type === Comment // potential v-if branch switch + ); +}; +function shouldUpdateComponent(prevVNode, nextVNode, optimized) { + const { props: prevProps, children: prevChildren, component } = prevVNode; + const { props: nextProps, children: nextChildren, patchFlag } = nextVNode; + const emits = component.emitsOptions; + // Parent component's render function was hot-updated. Since this may have + // caused the child component's slots content to have changed, we need to + // force the child to update as well. + if ((process.env.NODE_ENV !== 'production') && (prevChildren || nextChildren) && isHmrUpdating) { + return true; + } + // force child update for runtime directive or transition on component vnode. + if (nextVNode.dirs || nextVNode.transition) { + return true; + } + if (optimized && patchFlag > 0) { + if (patchFlag & 1024 /* DYNAMIC_SLOTS */) { + // slot content that references values that might have changed, + // e.g. in a v-for + return true; + } + if (patchFlag & 16 /* FULL_PROPS */) { + if (!prevProps) { + return !!nextProps; + } + // presence of this flag indicates props are always non-null + return hasPropsChanged(prevProps, nextProps, emits); + } + else if (patchFlag & 8 /* PROPS */) { + const dynamicProps = nextVNode.dynamicProps; + for (let i = 0; i < dynamicProps.length; i++) { + const key = dynamicProps[i]; + if (nextProps[key] !== prevProps[key] && + !isEmitListener(emits, key)) { + return true; + } + } + } + } + else { + // this path is only taken by manually written render functions + // so presence of any children leads to a forced update + if (prevChildren || nextChildren) { + if (!nextChildren || !nextChildren.$stable) { + return true; + } + } + if (prevProps === nextProps) { + return false; + } + if (!prevProps) { + return !!nextProps; + } + if (!nextProps) { + return true; + } + return hasPropsChanged(prevProps, nextProps, emits); + } + return false; +} +function hasPropsChanged(prevProps, nextProps, emitsOptions) { + const nextKeys = Object.keys(nextProps); + if (nextKeys.length !== Object.keys(prevProps).length) { + return true; + } + for (let i = 0; i < nextKeys.length; i++) { + const key = nextKeys[i]; + if (nextProps[key] !== prevProps[key] && + !isEmitListener(emitsOptions, key)) { + return true; + } + } + return false; +} +function updateHOCHostEl({ vnode, parent }, el // HostNode +) { + while (parent && parent.subTree === vnode) { + (vnode = parent.vnode).el = el; + parent = parent.parent; + } } -/** - * Wrap a slot function to memoize current rendering instance - * @private - */ -function withCtx(fn, ctx = currentRenderingInstance) { - if (!ctx) return fn - const renderFnWithContext = (...args) => { - // If a user calls a compiled slot inside a template expression (#1745), it - // can mess up block tracking, so by default we need to push a null block to - // avoid that. This isn't necessary if rendering a compiled ``. - if (!isRenderingCompiledSlot) { - openBlock(true /* null block that disables tracking */); - } - const owner = currentRenderingInstance; - setCurrentRenderingInstance(ctx); - const res = fn(...args); - setCurrentRenderingInstance(owner); - if (!isRenderingCompiledSlot) { - closeBlock(); - } - return res - }; - renderFnWithContext._c = true; - return renderFnWithContext +const isSuspense = (type) => type.__isSuspense; +// Suspense exposes a component-like API, and is treated like a component +// in the compiler, but internally it's a special built-in type that hooks +// directly into the renderer. +const SuspenseImpl = { + // In order to make Suspense tree-shakable, we need to avoid importing it + // directly in the renderer. The renderer checks for the __isSuspense flag + // on a vnode's type and calls the `process` method, passing in renderer + // internals. + __isSuspense: true, + process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, + // platform-specific impl passed from renderer + rendererInternals) { + if (n1 == null) { + mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, rendererInternals); + } + else { + patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized, rendererInternals); + } + }, + hydrate: hydrateSuspense, + create: createSuspenseBoundary +}; +// Force-casted public typing for h and TSX props inference +const Suspense = ( SuspenseImpl + ); +function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, optimized, rendererInternals) { + const { p: patch, o: { createElement } } = rendererInternals; + const hiddenContainer = createElement('div'); + const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized, rendererInternals)); + // start mounting the content subtree in an off-dom container + patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, optimized); + // now check if we have encountered any async deps + if (suspense.deps > 0) { + // has async + // mount the fallback tree + patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context + isSVG, optimized); + setActiveBranch(suspense, vnode.ssFallback); + } + else { + // Suspense has no async deps. Just resolve. + suspense.resolve(); + } +} +function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized, { p: patch, um: unmount, o: { createElement } }) { + const suspense = (n2.suspense = n1.suspense); + suspense.vnode = n2; + n2.el = n1.el; + const newBranch = n2.ssContent; + const newFallback = n2.ssFallback; + const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense; + if (pendingBranch) { + suspense.pendingBranch = newBranch; + if (isSameVNodeType(newBranch, pendingBranch)) { + // same root type but content may have changed. + patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized); + if (suspense.deps <= 0) { + suspense.resolve(); + } + else if (isInFallback) { + patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context + isSVG, optimized); + setActiveBranch(suspense, newFallback); + } + } + else { + // toggled before pending tree is resolved + suspense.pendingId++; + if (isHydrating) { + // if toggled before hydration is finished, the current DOM tree is + // no longer valid. set it as the active branch so it will be unmounted + // when resolved + suspense.isHydrating = false; + suspense.activeBranch = pendingBranch; + } + else { + unmount(pendingBranch, parentComponent, suspense); + } + // increment pending ID. this is used to invalidate async callbacks + // reset suspense state + suspense.deps = 0; + // discard effects from pending branch + suspense.effects.length = 0; + // discard previous container + suspense.hiddenContainer = createElement('div'); + if (isInFallback) { + // already in fallback state + patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized); + if (suspense.deps <= 0) { + suspense.resolve(); + } + else { + patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context + isSVG, optimized); + setActiveBranch(suspense, newFallback); + } + } + else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) { + // toggled "back" to current active branch + patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, optimized); + // force resolve + suspense.resolve(true); + } + else { + // switched to a 3rd branch + patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized); + if (suspense.deps <= 0) { + suspense.resolve(); + } + } + } + } + else { + if (activeBranch && isSameVNodeType(newBranch, activeBranch)) { + // root did not change, just normal patch + patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, optimized); + setActiveBranch(suspense, newBranch); + } + else { + // root node toggled + // invoke @pending event + const onPending = n2.props && n2.props.onPending; + if (isFunction(onPending)) { + onPending(); + } + // mount pending branch in off-dom container + suspense.pendingBranch = newBranch; + suspense.pendingId++; + patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized); + if (suspense.deps <= 0) { + // incoming branch has no async deps, resolve now. + suspense.resolve(); + } + else { + const { timeout, pendingId } = suspense; + if (timeout > 0) { + setTimeout(() => { + if (suspense.pendingId === pendingId) { + suspense.fallback(newFallback); + } + }, timeout); + } + else if (timeout === 0) { + suspense.fallback(newFallback); + } + } + } + } +} +let hasWarned = false; +function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, optimized, rendererInternals, isHydrating = false) { + /* istanbul ignore if */ + if ((process.env.NODE_ENV !== 'production') && !false && !hasWarned) { + hasWarned = true; + // @ts-ignore `console.info` cannot be null error + console[console.info ? 'info' : 'log'](` is an experimental feature and its API will likely change.`); + } + const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals; + const timeout = toNumber(vnode.props && vnode.props.timeout); + const suspense = { + vnode, + parent, + parentComponent, + isSVG, + optimized, + container, + hiddenContainer, + anchor, + deps: 0, + pendingId: 0, + timeout: typeof timeout === 'number' ? timeout : -1, + activeBranch: null, + pendingBranch: null, + isInFallback: true, + isHydrating, + isUnmounted: false, + effects: [], + resolve(resume = false) { + if ((process.env.NODE_ENV !== 'production')) { + if (!resume && !suspense.pendingBranch) { + throw new Error(`suspense.resolve() is called without a pending branch.`); + } + if (suspense.isUnmounted) { + throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`); + } + } + const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense; + if (suspense.isHydrating) { + suspense.isHydrating = false; + } + else if (!resume) { + const delayEnter = activeBranch && + pendingBranch.transition && + pendingBranch.transition.mode === 'out-in'; + if (delayEnter) { + activeBranch.transition.afterLeave = () => { + if (pendingId === suspense.pendingId) { + move(pendingBranch, container, anchor, 0 /* ENTER */); + } + }; + } + // this is initial anchor on mount + let { anchor } = suspense; + // unmount current active tree + if (activeBranch) { + // if the fallback tree was mounted, it may have been moved + // as part of a parent suspense. get the latest anchor for insertion + anchor = next(activeBranch); + unmount(activeBranch, parentComponent, suspense, true); + } + if (!delayEnter) { + // move content from off-dom container to actual container + move(pendingBranch, container, anchor, 0 /* ENTER */); + } + } + setActiveBranch(suspense, pendingBranch); + suspense.pendingBranch = null; + suspense.isInFallback = false; + // flush buffered effects + // check if there is a pending parent suspense + let parent = suspense.parent; + let hasUnresolvedAncestor = false; + while (parent) { + if (parent.pendingBranch) { + // found a pending parent suspense, merge buffered post jobs + // into that parent + parent.effects.push(...effects); + hasUnresolvedAncestor = true; + break; + } + parent = parent.parent; + } + // no pending parent suspense, flush all jobs + if (!hasUnresolvedAncestor) { + queuePostFlushCb(effects); + } + suspense.effects = []; + // invoke @resolve event + const onResolve = vnode.props && vnode.props.onResolve; + if (isFunction(onResolve)) { + onResolve(); + } + }, + fallback(fallbackVNode) { + if (!suspense.pendingBranch) { + return; + } + const { vnode, activeBranch, parentComponent, container, isSVG, optimized } = suspense; + // invoke @fallback event + const onFallback = vnode.props && vnode.props.onFallback; + if (isFunction(onFallback)) { + onFallback(); + } + const anchor = next(activeBranch); + const mountFallback = () => { + if (!suspense.isInFallback) { + return; + } + // mount the fallback tree + patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context + isSVG, optimized); + setActiveBranch(suspense, fallbackVNode); + }; + const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in'; + if (delayEnter) { + activeBranch.transition.afterLeave = mountFallback; + } + // unmount current active branch + unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now + true // shouldRemove + ); + suspense.isInFallback = true; + if (!delayEnter) { + mountFallback(); + } + }, + move(container, anchor, type) { + suspense.activeBranch && + move(suspense.activeBranch, container, anchor, type); + suspense.container = container; + }, + next() { + return suspense.activeBranch && next(suspense.activeBranch); + }, + registerDep(instance, setupRenderEffect) { + if (!suspense.pendingBranch) { + return; + } + const hydratedEl = instance.vnode.el; + suspense.deps++; + instance + .asyncDep.catch(err => { + handleError(err, instance, 0 /* SETUP_FUNCTION */); + }) + .then(asyncSetupResult => { + // retry when the setup() promise resolves. + // component may have been unmounted before resolve. + if (instance.isUnmounted || + suspense.isUnmounted || + suspense.pendingId !== instance.suspenseId) { + return; + } + suspense.deps--; + // retry from this component + instance.asyncResolved = true; + const { vnode } = instance; + if ((process.env.NODE_ENV !== 'production')) { + pushWarningContext(vnode); + } + handleSetupResult(instance, asyncSetupResult); + if (hydratedEl) { + // vnode may have been replaced if an update happened before the + // async dep is resolved. + vnode.el = hydratedEl; + } + const placeholder = !hydratedEl && instance.subTree.el; + setupRenderEffect(instance, vnode, + // component may have been moved before resolve. + // if this is not a hydration, instance.subTree will be the comment + // placeholder. + parentNode(hydratedEl || instance.subTree.el), + // anchor will not be used if this is hydration, so only need to + // consider the comment placeholder case. + hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized); + if (placeholder) { + remove(placeholder); + } + updateHOCHostEl(instance, vnode.el); + if ((process.env.NODE_ENV !== 'production')) { + popWarningContext(); + } + if (suspense.deps === 0) { + suspense.resolve(); + } + }); + }, + unmount(parentSuspense, doRemove) { + suspense.isUnmounted = true; + if (suspense.activeBranch) { + unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove); + } + if (suspense.pendingBranch) { + unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove); + } + } + }; + return suspense; +} +function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, optimized, rendererInternals, hydrateNode) { + /* eslint-disable no-restricted-globals */ + const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, optimized, rendererInternals, true /* hydrating */)); + // there are two possible scenarios for server-rendered suspense: + // - success: ssr content should be fully resolved + // - failure: ssr content should be the fallback branch. + // however, on the client we don't really know if it has failed or not + // attempt to hydrate the DOM assuming it has succeeded, but we still + // need to construct a suspense boundary first + const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, optimized); + if (suspense.deps === 0) { + suspense.resolve(); + } + return result; + /* eslint-enable no-restricted-globals */ +} +function normalizeSuspenseChildren(vnode) { + const { shapeFlag, children } = vnode; + let content; + let fallback; + if (shapeFlag & 32 /* SLOTS_CHILDREN */) { + content = normalizeSuspenseSlot(children.default); + fallback = normalizeSuspenseSlot(children.fallback); + } + else { + content = normalizeSuspenseSlot(children); + fallback = normalizeVNode(null); + } + return { + content, + fallback + }; +} +function normalizeSuspenseSlot(s) { + if (isFunction(s)) { + s = s(); + } + if (isArray(s)) { + const singleChild = filterSingleRoot(s); + if ((process.env.NODE_ENV !== 'production') && !singleChild) { + warn(` slots expect a single root node.`); + } + s = singleChild; + } + return normalizeVNode(s); +} +function queueEffectWithSuspense(fn, suspense) { + if (suspense && suspense.pendingBranch) { + if (isArray(fn)) { + suspense.effects.push(...fn); + } + else { + suspense.effects.push(fn); + } + } + else { + queuePostFlushCb(fn); + } +} +function setActiveBranch(suspense, branch) { + suspense.activeBranch = branch; + const { vnode, parentComponent } = suspense; + const el = (vnode.el = branch.el); + // in case suspense is the root node of a component, + // recursively update the HOC el + if (parentComponent && parentComponent.subTree === vnode) { + parentComponent.vnode.el = el; + updateHOCHostEl(parentComponent, el); + } } -// SFC scoped style ID management. -let currentScopeId = null; -const scopeIdStack = []; -/** - * @private - */ -function pushScopeId(id) { - scopeIdStack.push((currentScopeId = id)); -} -/** - * @private - */ -function popScopeId() { - scopeIdStack.pop(); - currentScopeId = scopeIdStack[scopeIdStack.length - 1] || null; -} -/** - * @private - */ -function withScopeId(id) { - return fn => - withCtx(function() { - pushScopeId(id); - const res = fn.apply(this, arguments); - popScopeId(); - return res - }) +let isRenderingCompiledSlot = 0; +const setCompiledSlotRendering = (n) => (isRenderingCompiledSlot += n); +/** + * Compiler runtime helper for rendering `` + * @private + */ +function renderSlot(slots, name, props = {}, +// this is not a user-facing function, so the fallback is always generated by +// the compiler and guaranteed to be a function returning an array +fallback) { + let slot = slots[name]; + if ((process.env.NODE_ENV !== 'production') && slot && slot.length > 1) { + warn(`SSR-optimized slot function detected in a non-SSR-optimized render ` + + `function. You need to mark this component with $dynamic-slots in the ` + + `parent template.`); + slot = () => []; + } + // a compiled slot disables block tracking by default to avoid manual + // invocation interfering with template-based block tracking, but in + // `renderSlot` we can be sure that it's template-based so we can force + // enable it. + isRenderingCompiledSlot++; + const rendered = (openBlock(), + createBlock(Fragment, { key: props.key }, slot ? slot(props) : fallback ? fallback() : [], slots._ === 1 /* STABLE */ + ? 64 /* STABLE_FRAGMENT */ + : -2 /* BAIL */)); + isRenderingCompiledSlot--; + return rendered; } -const isTeleport = type => type.__isTeleport; -const isTeleportDisabled = props => - props && (props.disabled || props.disabled === ''); -const resolveTarget = (props, select) => { - const targetSelector = props && props.to; - if (isString(targetSelector)) { - if (!select) { - process.env.NODE_ENV !== 'production' && - warn( - `Current renderer does not support string target for Teleports. ` + - `(missing querySelector renderer option)` - ); - return null - } else { - const target = select(targetSelector); - if (!target) { - process.env.NODE_ENV !== 'production' && - warn( - `Failed to locate Teleport target with selector "${targetSelector}". ` + - `Note the target element must exist before the component is mounted - ` + - `i.e. the target cannot be rendered by the component itself, and ` + - `ideally should be outside of the entire Vue component tree.` - ); - } - return target - } - } else { - if ( - process.env.NODE_ENV !== 'production' && - !targetSelector && - !isTeleportDisabled(props) - ) { - warn(`Invalid Teleport target: ${targetSelector}`); - } - return targetSelector - } -}; -const TeleportImpl = { - __isTeleport: true, - process( - n1, - n2, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized, - internals - ) { - const { - mc: mountChildren, - pc: patchChildren, - pbc: patchBlockChildren, - o: { insert, querySelector, createText, createComment } - } = internals; - const disabled = isTeleportDisabled(n2.props); - const { shapeFlag, children } = n2; - if (n1 == null) { - // insert anchors in the main view - const placeholder = (n2.el = - process.env.NODE_ENV !== 'production' - ? createComment('teleport start') - : createText('')); - const mainAnchor = (n2.anchor = - process.env.NODE_ENV !== 'production' - ? createComment('teleport end') - : createText('')); - insert(placeholder, container, anchor); - insert(mainAnchor, container, anchor); - const target = (n2.target = resolveTarget(n2.props, querySelector)); - const targetAnchor = (n2.targetAnchor = createText('')); - if (target) { - insert(targetAnchor, target); - } else if (process.env.NODE_ENV !== 'production' && !disabled) { - warn('Invalid Teleport target on mount:', target, `(${typeof target})`); - } - const mount = (container, anchor) => { - // Teleport *always* has Array children. This is enforced in both the - // compiler and vnode children normalization. - if (shapeFlag & 16 /* ARRAY_CHILDREN */) { - mountChildren( - children, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized - ); - } - }; - if (disabled) { - mount(container, mainAnchor); - } else if (target) { - mount(target, targetAnchor); - } - } else { - // update content - n2.el = n1.el; - const mainAnchor = (n2.anchor = n1.anchor); - const target = (n2.target = n1.target); - const targetAnchor = (n2.targetAnchor = n1.targetAnchor); - const wasDisabled = isTeleportDisabled(n1.props); - const currentContainer = wasDisabled ? container : target; - const currentAnchor = wasDisabled ? mainAnchor : targetAnchor; - if (n2.dynamicChildren) { - // fast path when the teleport happens to be a block root - patchBlockChildren( - n1.dynamicChildren, - n2.dynamicChildren, - currentContainer, - parentComponent, - parentSuspense, - isSVG - ); - // even in block tree mode we need to make sure all root-level nodes - // in the teleport inherit previous DOM references so that they can - // be moved in future patches. - if (n2.shapeFlag & 16 /* ARRAY_CHILDREN */) { - const oldChildren = n1.children; - const children = n2.children; - for (let i = 0; i < children.length; i++) { - // only inherit for non-patched nodes (i.e. static ones) - if (!children[i].el) { - children[i].el = oldChildren[i].el; - } - } - } - } else if (!optimized) { - patchChildren( - n1, - n2, - currentContainer, - currentAnchor, - parentComponent, - parentSuspense, - isSVG - ); - } - if (disabled) { - if (!wasDisabled) { - // enabled -> disabled - // move into main container - moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */); - } - } else { - // target changed - if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) { - const nextTarget = (n2.target = resolveTarget( - n2.props, - querySelector - )); - if (nextTarget) { - moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */); - } else if (process.env.NODE_ENV !== 'production') { - warn( - 'Invalid Teleport target on update:', - target, - `(${typeof target})` - ); - } - } else if (wasDisabled) { - // disabled -> enabled - // move into teleport target - moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */); - } - } - } - }, - remove( - vnode, - { - r: remove, - o: { remove: hostRemove } - } - ) { - const { shapeFlag, children, anchor } = vnode; - hostRemove(anchor); - if (shapeFlag & 16 /* ARRAY_CHILDREN */) { - for (let i = 0; i < children.length; i++) { - remove(children[i]); - } - } - }, - move: moveTeleport, - hydrate: hydrateTeleport -}; -function moveTeleport( - vnode, - container, - parentAnchor, - { o: { insert }, m: move }, - moveType = 2 /* REORDER */ -) { - // move target anchor if this is a target change. - if (moveType === 0 /* TARGET_CHANGE */) { - insert(vnode.targetAnchor, container, parentAnchor); - } - const { el, anchor, shapeFlag, children, props } = vnode; - const isReorder = moveType === 2; /* REORDER */ - // move main view anchor if this is a re-order. - if (isReorder) { - insert(el, container, parentAnchor); - } - // if this is a re-order and teleport is enabled (content is in target) - // do not move children. So the opposite is: only move children if this - // is not a reorder, or the teleport is disabled - if (!isReorder || isTeleportDisabled(props)) { - // Teleport has either Array children or no children. - if (shapeFlag & 16 /* ARRAY_CHILDREN */) { - for (let i = 0; i < children.length; i++) { - move(children[i], container, parentAnchor, 2 /* REORDER */); - } - } - } - // move main view anchor if this is a re-order. - if (isReorder) { - insert(anchor, container, parentAnchor); - } -} -function hydrateTeleport( - node, - vnode, - parentComponent, - parentSuspense, - optimized, - { o: { nextSibling, parentNode, querySelector } }, - hydrateChildren -) { - const target = (vnode.target = resolveTarget(vnode.props, querySelector)); - if (target) { - // if multiple teleports rendered to the same target element, we need to - // pick up from where the last teleport finished instead of the first node - const targetNode = target._lpa || target.firstChild; - if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) { - if (isTeleportDisabled(vnode.props)) { - vnode.anchor = hydrateChildren( - nextSibling(node), - vnode, - parentNode(node), - parentComponent, - parentSuspense, - optimized - ); - vnode.targetAnchor = targetNode; - } else { - vnode.anchor = nextSibling(node); - vnode.targetAnchor = hydrateChildren( - targetNode, - vnode, - target, - parentComponent, - parentSuspense, - optimized - ); - } - target._lpa = vnode.targetAnchor && nextSibling(vnode.targetAnchor); - } - } - return vnode.anchor && nextSibling(vnode.anchor) +/** + * Wrap a slot function to memoize current rendering instance + * @private + */ +function withCtx(fn, ctx = currentRenderingInstance) { + if (!ctx) + return fn; + const renderFnWithContext = (...args) => { + // If a user calls a compiled slot inside a template expression (#1745), it + // can mess up block tracking, so by default we need to push a null block to + // avoid that. This isn't necessary if rendering a compiled ``. + if (!isRenderingCompiledSlot) { + openBlock(true /* null block that disables tracking */); + } + const owner = currentRenderingInstance; + setCurrentRenderingInstance(ctx); + const res = fn(...args); + setCurrentRenderingInstance(owner); + if (!isRenderingCompiledSlot) { + closeBlock(); + } + return res; + }; + renderFnWithContext._c = true; + return renderFnWithContext; } -// Force-casted public typing for h and TSX props inference -const Teleport = TeleportImpl; -const COMPONENTS = 'components'; -const DIRECTIVES = 'directives'; -/** - * @private - */ -function resolveComponent(name) { - return resolveAsset(COMPONENTS, name) || name -} -const NULL_DYNAMIC_COMPONENT = Symbol(); -/** - * @private - */ -function resolveDynamicComponent(component) { - if (isString(component)) { - return resolveAsset(COMPONENTS, component, false) || component - } else { - // invalid types will fallthrough to createVNode and raise warning - return component || NULL_DYNAMIC_COMPONENT - } -} -/** - * @private - */ -function resolveDirective(name) { - return resolveAsset(DIRECTIVES, name) -} -// implementation -function resolveAsset(type, name, warnMissing = true) { - const instance = currentRenderingInstance || currentInstance; - if (instance) { - const Component = instance.type; - // self name has highest priority - if (type === COMPONENTS) { - const selfName = Component.displayName || Component.name; - if ( - selfName && - (selfName === name || - selfName === camelize(name) || - selfName === capitalize(camelize(name))) - ) { - return Component - } - } - const res = - // local registration - // check instance[type] first for components with mixin or extends. - resolve(instance[type] || Component[type], name) || - // global registration - resolve(instance.appContext[type], name); - if (process.env.NODE_ENV !== 'production' && warnMissing && !res) { - warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`); - } - return res - } else if (process.env.NODE_ENV !== 'production') { - warn( - `resolve${capitalize(type.slice(0, -1))} ` + - `can only be used in render() or setup().` - ); - } -} -function resolve(registry, name) { - return ( - registry && - (registry[name] || - registry[camelize(name)] || - registry[capitalize(camelize(name))]) - ) +// SFC scoped style ID management. +let currentScopeId = null; +const scopeIdStack = []; +/** + * @private + */ +function pushScopeId(id) { + scopeIdStack.push((currentScopeId = id)); +} +/** + * @private + */ +function popScopeId() { + scopeIdStack.pop(); + currentScopeId = scopeIdStack[scopeIdStack.length - 1] || null; +} +/** + * @private + */ +function withScopeId(id) { + return ((fn) => withCtx(function () { + pushScopeId(id); + const res = fn.apply(this, arguments); + popScopeId(); + return res; + })); } -const Fragment = Symbol( - process.env.NODE_ENV !== 'production' ? 'Fragment' : undefined -); -const Text = Symbol(process.env.NODE_ENV !== 'production' ? 'Text' : undefined); -const Comment = Symbol( - process.env.NODE_ENV !== 'production' ? 'Comment' : undefined -); -const Static = Symbol( - process.env.NODE_ENV !== 'production' ? 'Static' : undefined -); -// Since v-if and v-for are the two possible ways node structure can dynamically -// change, once we consider v-if branches and each v-for fragment a block, we -// can divide a template into nested blocks, and within each block the node -// structure would be stable. This allows us to skip most children diffing -// and only worry about the dynamic nodes (indicated by patch flags). -const blockStack = []; -let currentBlock = null; -/** - * Open a block. - * This must be called before `createBlock`. It cannot be part of `createBlock` - * because the children of the block are evaluated before `createBlock` itself - * is called. The generated code typically looks like this: - * - * ```js - * function render() { - * return (openBlock(),createBlock('div', null, [...])) - * } - * ``` - * disableTracking is true when creating a v-for fragment block, since a v-for - * fragment always diffs its children. - * - * @private - */ -function openBlock(disableTracking = false) { - blockStack.push((currentBlock = disableTracking ? null : [])); -} -function closeBlock() { - blockStack.pop(); - currentBlock = blockStack[blockStack.length - 1] || null; -} -// Whether we should be tracking dynamic child nodes inside a block. -// Only tracks when this value is > 0 -// We are not using a simple boolean because this value may need to be -// incremented/decremented by nested usage of v-once (see below) -let shouldTrack$1 = 1; -/** - * Block tracking sometimes needs to be disabled, for example during the - * creation of a tree that needs to be cached by v-once. The compiler generates - * code like this: - * - * ``` js - * _cache[1] || ( - * setBlockTracking(-1), - * _cache[1] = createVNode(...), - * setBlockTracking(1), - * _cache[1] - * ) - * ``` - * - * @private - */ -function setBlockTracking(value) { - shouldTrack$1 += value; -} -/** - * Create a block root vnode. Takes the same exact arguments as `createVNode`. - * A block root keeps track of dynamic nodes within the block in the - * `dynamicChildren` array. - * - * @private - */ -function createBlock(type, props, children, patchFlag, dynamicProps) { - const vnode = createVNode( - type, - props, - children, - patchFlag, - dynamicProps, - true /* isBlock: prevent a block from tracking itself */ - ); - // save current block children on the block vnode - vnode.dynamicChildren = currentBlock || EMPTY_ARR; - // close block - closeBlock(); - // a block is always going to be patched, so track it as a child of its - // parent block - if (shouldTrack$1 > 0 && currentBlock) { - currentBlock.push(vnode); - } - return vnode -} -function isVNode(value) { - return value ? value.__v_isVNode === true : false -} -function isSameVNodeType(n1, n2) { - if ( - process.env.NODE_ENV !== 'production' && - n2.shapeFlag & 6 /* COMPONENT */ && - hmrDirtyComponents.has(n2.type) - ) { - // HMR only: if the component has been hot-updated, force a reload. - return false - } - return n1.type === n2.type && n1.key === n2.key -} -let vnodeArgsTransformer; -/** - * Internal API for registering an arguments transform for createVNode - * used for creating stubs in the test-utils - * It is *internal* but needs to be exposed for test-utils to pick up proper - * typings - */ -function transformVNodeArgs(transformer) { - vnodeArgsTransformer = transformer; -} -const createVNodeWithArgsTransform = (...args) => { - return _createVNode( - ...(vnodeArgsTransformer - ? vnodeArgsTransformer(args, currentRenderingInstance) - : args) - ) -}; -const InternalObjectKey = `__vInternal`; -const normalizeKey = ({ key }) => (key != null ? key : null); -const normalizeRef = ({ ref }) => { - return ref != null - ? isArray(ref) - ? ref - : [currentRenderingInstance, ref] - : null -}; -const createVNode = - process.env.NODE_ENV !== 'production' - ? createVNodeWithArgsTransform - : _createVNode; -function _createVNode( - type, - props = null, - children = null, - patchFlag = 0, - dynamicProps = null, - isBlockNode = false -) { - if (!type || type === NULL_DYNAMIC_COMPONENT) { - if (process.env.NODE_ENV !== 'production' && !type) { - warn(`Invalid vnode type when creating vnode: ${type}.`); - } - type = Comment; - } - if (isVNode(type)) { - const cloned = cloneVNode(type, props); - if (children) { - normalizeChildren(cloned, children); - } - return cloned - } - // class component normalization. - if (isFunction(type) && '__vccOpts' in type) { - type = type.__vccOpts; - } - // class & style normalization. - if (props) { - // for reactive or proxy objects, we need to clone it to enable mutation. - if (isProxy(props) || InternalObjectKey in props) { - props = extend({}, props); - } - let { class: klass, style } = props; - if (klass && !isString(klass)) { - props.class = normalizeClass(klass); - } - if (isObject(style)) { - // reactive state objects need to be cloned since they are likely to be - // mutated - if (isProxy(style) && !isArray(style)) { - style = extend({}, style); - } - props.style = normalizeStyle(style); - } - } - // encode the vnode type information into a bitmap - const shapeFlag = isString(type) - ? 1 /* ELEMENT */ - : isSuspense(type) - ? 128 /* SUSPENSE */ - : isTeleport(type) - ? 64 /* TELEPORT */ - : isObject(type) - ? 4 /* STATEFUL_COMPONENT */ - : isFunction(type) - ? 2 /* FUNCTIONAL_COMPONENT */ - : 0; - if ( - process.env.NODE_ENV !== 'production' && - shapeFlag & 4 /* STATEFUL_COMPONENT */ && - isProxy(type) - ) { - type = toRaw(type); - warn( - `Vue received a Component which was made a reactive object. This can ` + - `lead to unnecessary performance overhead, and should be avoided by ` + - `marking the component with \`markRaw\` or using \`shallowRef\` ` + - `instead of \`ref\`.`, - `\nComponent that was made reactive: `, - type - ); - } - const vnode = { - __v_isVNode: true, - ['__v_skip' /* SKIP */]: true, - type, - props, - key: props && normalizeKey(props), - ref: props && normalizeRef(props), - scopeId: currentScopeId, - children: null, - component: null, - suspense: null, - dirs: null, - transition: null, - el: null, - anchor: null, - target: null, - targetAnchor: null, - staticCount: 0, - shapeFlag, - patchFlag, - dynamicProps, - dynamicChildren: null, - appContext: null - }; - // validate key - if (process.env.NODE_ENV !== 'production' && vnode.key !== vnode.key) { - warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type); - } - normalizeChildren(vnode, children); - if ( - shouldTrack$1 > 0 && - // avoid a block node from tracking itself - !isBlockNode && - // has current parent block - currentBlock && - // presence of a patch flag indicates this node needs patching on updates. - // component nodes also should always be patched, because even if the - // component doesn't need to update, it needs to persist the instance on to - // the next vnode so that it can be properly unmounted later. - (patchFlag > 0 || shapeFlag & 6) /* COMPONENT */ && - // the EVENTS flag is only for hydration and if it is the only flag, the - // vnode should not be considered dynamic due to handler caching. - patchFlag !== 32 /* HYDRATE_EVENTS */ - ) { - currentBlock.push(vnode); - } - return vnode -} -function cloneVNode(vnode, extraProps) { - // This is intentionally NOT using spread or extend to avoid the runtime - // key enumeration cost. - const { props, patchFlag } = vnode; - const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props; - return { - __v_isVNode: true, - ['__v_skip' /* SKIP */]: true, - type: vnode.type, - props: mergedProps, - key: mergedProps && normalizeKey(mergedProps), - ref: extraProps && extraProps.ref ? normalizeRef(extraProps) : vnode.ref, - scopeId: vnode.scopeId, - children: vnode.children, - target: vnode.target, - targetAnchor: vnode.targetAnchor, - staticCount: vnode.staticCount, - shapeFlag: vnode.shapeFlag, - // if the vnode is cloned with extra props, we can no longer assume its - // existing patch flag to be reliable and need to add the FULL_PROPS flag. - // note: perserve flag for fragments since they use the flag for children - // fast paths only. - patchFlag: - extraProps && vnode.type !== Fragment - ? patchFlag === -1 // hoisted node - ? 16 /* FULL_PROPS */ - : patchFlag | 16 /* FULL_PROPS */ - : patchFlag, - dynamicProps: vnode.dynamicProps, - dynamicChildren: vnode.dynamicChildren, - appContext: vnode.appContext, - dirs: vnode.dirs, - transition: vnode.transition, - // These should technically only be non-null on mounted VNodes. However, - // they *should* be copied for kept-alive vnodes. So we just always copy - // them since them being non-null during a mount doesn't affect the logic as - // they will simply be overwritten. - component: vnode.component, - suspense: vnode.suspense, - el: vnode.el, - anchor: vnode.anchor - } -} -/** - * @private - */ -function createTextVNode(text = ' ', flag = 0) { - return createVNode(Text, null, text, flag) -} -/** - * @private - */ -function createStaticVNode(content, numberOfNodes) { - // A static vnode can contain multiple stringified elements, and the number - // of elements is necessary for hydration. - const vnode = createVNode(Static, null, content); - vnode.staticCount = numberOfNodes; - return vnode -} -/** - * @private - */ -function createCommentVNode( - text = '', - // when used as the v-else branch, the comment node must be created as a - // block to ensure correct updates. - asBlock = false -) { - return asBlock - ? (openBlock(), createBlock(Comment, null, text)) - : createVNode(Comment, null, text) -} -function normalizeVNode(child) { - if (child == null || typeof child === 'boolean') { - // empty placeholder - return createVNode(Comment) - } else if (isArray(child)) { - // fragment - return createVNode(Fragment, null, child) - } else if (typeof child === 'object') { - // already vnode, this should be the most common since compiled templates - // always produce all-vnode children arrays - return child.el === null ? child : cloneVNode(child) - } else { - // strings and numbers - return createVNode(Text, null, String(child)) - } -} -// optimized normalization for template-compiled render fns -function cloneIfMounted(child) { - return child.el === null ? child : cloneVNode(child) -} -function normalizeChildren(vnode, children) { - let type = 0; - const { shapeFlag } = vnode; - if (children == null) { - children = null; - } else if (isArray(children)) { - type = 16; /* ARRAY_CHILDREN */ - } else if (typeof children === 'object') { - if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 64 /* TELEPORT */) { - // Normalize slot to plain children for plain element and Teleport - const slot = children.default; - if (slot) { - // _c marker is added by withCtx() indicating this is a compiled slot - slot._c && setCompiledSlotRendering(1); - normalizeChildren(vnode, slot()); - slot._c && setCompiledSlotRendering(-1); - } - return - } else { - type = 32; /* SLOTS_CHILDREN */ - const slotFlag = children._; - if (!slotFlag && !(InternalObjectKey in children)) { - children._ctx = currentRenderingInstance; - } else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) { - // a child component receives forwarded slots from the parent. - // its slot type is determined by its parent's slot type. - if ( - currentRenderingInstance.vnode.patchFlag & 1024 /* DYNAMIC_SLOTS */ - ) { - children._ = 2; /* DYNAMIC */ - vnode.patchFlag |= 1024; /* DYNAMIC_SLOTS */ - } else { - children._ = 1; /* STABLE */ - } - } - } - } else if (isFunction(children)) { - children = { default: children, _ctx: currentRenderingInstance }; - type = 32; /* SLOTS_CHILDREN */ - } else { - children = String(children); - // force teleport children to array so it can be moved around - if (shapeFlag & 64 /* TELEPORT */) { - type = 16; /* ARRAY_CHILDREN */ - children = [createTextVNode(children)]; - } else { - type = 8; /* TEXT_CHILDREN */ - } - } - vnode.children = children; - vnode.shapeFlag |= type; -} -function mergeProps(...args) { - const ret = extend({}, args[0]); - for (let i = 1; i < args.length; i++) { - const toMerge = args[i]; - for (const key in toMerge) { - if (key === 'class') { - if (ret.class !== toMerge.class) { - ret.class = normalizeClass([ret.class, toMerge.class]); - } - } else if (key === 'style') { - ret.style = normalizeStyle([ret.style, toMerge.style]); - } else if (isOn(key)) { - const existing = ret[key]; - const incoming = toMerge[key]; - if (existing !== incoming) { - ret[key] = existing ? [].concat(existing, toMerge[key]) : incoming; - } - } else { - ret[key] = toMerge[key]; - } - } - } - return ret -} +const isTeleport = (type) => type.__isTeleport; +const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === ''); +const resolveTarget = (props, select) => { + const targetSelector = props && props.to; + if (isString(targetSelector)) { + if (!select) { + (process.env.NODE_ENV !== 'production') && + warn(`Current renderer does not support string target for Teleports. ` + + `(missing querySelector renderer option)`); + return null; + } + else { + const target = select(targetSelector); + if (!target) { + (process.env.NODE_ENV !== 'production') && + warn(`Failed to locate Teleport target with selector "${targetSelector}". ` + + `Note the target element must exist before the component is mounted - ` + + `i.e. the target cannot be rendered by the component itself, and ` + + `ideally should be outside of the entire Vue component tree.`); + } + return target; + } + } + else { + if ((process.env.NODE_ENV !== 'production') && !targetSelector && !isTeleportDisabled(props)) { + warn(`Invalid Teleport target: ${targetSelector}`); + } + return targetSelector; + } +}; +const TeleportImpl = { + __isTeleport: true, + process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals) { + const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals; + const disabled = isTeleportDisabled(n2.props); + const { shapeFlag, children } = n2; + if (n1 == null) { + // insert anchors in the main view + const placeholder = (n2.el = (process.env.NODE_ENV !== 'production') + ? createComment('teleport start') + : createText('')); + const mainAnchor = (n2.anchor = (process.env.NODE_ENV !== 'production') + ? createComment('teleport end') + : createText('')); + insert(placeholder, container, anchor); + insert(mainAnchor, container, anchor); + const target = (n2.target = resolveTarget(n2.props, querySelector)); + const targetAnchor = (n2.targetAnchor = createText('')); + if (target) { + insert(targetAnchor, target); + } + else if ((process.env.NODE_ENV !== 'production') && !disabled) { + warn('Invalid Teleport target on mount:', target, `(${typeof target})`); + } + const mount = (container, anchor) => { + // Teleport *always* has Array children. This is enforced in both the + // compiler and vnode children normalization. + if (shapeFlag & 16 /* ARRAY_CHILDREN */) { + mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, optimized); + } + }; + if (disabled) { + mount(container, mainAnchor); + } + else if (target) { + mount(target, targetAnchor); + } + } + else { + // update content + n2.el = n1.el; + const mainAnchor = (n2.anchor = n1.anchor); + const target = (n2.target = n1.target); + const targetAnchor = (n2.targetAnchor = n1.targetAnchor); + const wasDisabled = isTeleportDisabled(n1.props); + const currentContainer = wasDisabled ? container : target; + const currentAnchor = wasDisabled ? mainAnchor : targetAnchor; + if (n2.dynamicChildren) { + // fast path when the teleport happens to be a block root + patchBlockChildren(n1.dynamicChildren, n2.dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG); + // even in block tree mode we need to make sure all root-level nodes + // in the teleport inherit previous DOM references so that they can + // be moved in future patches. + if (n2.shapeFlag & 16 /* ARRAY_CHILDREN */) { + const oldChildren = n1.children; + const children = n2.children; + for (let i = 0; i < children.length; i++) { + // only inherit for non-patched nodes (i.e. static ones) + if (!children[i].el) { + children[i].el = oldChildren[i].el; + } + } + } + } + else if (!optimized) { + patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG); + } + if (disabled) { + if (!wasDisabled) { + // enabled -> disabled + // move into main container + moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */); + } + } + else { + // target changed + if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) { + const nextTarget = (n2.target = resolveTarget(n2.props, querySelector)); + if (nextTarget) { + moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */); + } + else if ((process.env.NODE_ENV !== 'production')) { + warn('Invalid Teleport target on update:', target, `(${typeof target})`); + } + } + else if (wasDisabled) { + // disabled -> enabled + // move into teleport target + moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */); + } + } + } + }, + remove(vnode, { r: remove, o: { remove: hostRemove } }) { + const { shapeFlag, children, anchor } = vnode; + hostRemove(anchor); + if (shapeFlag & 16 /* ARRAY_CHILDREN */) { + for (let i = 0; i < children.length; i++) { + remove(children[i]); + } + } + }, + move: moveTeleport, + hydrate: hydrateTeleport +}; +function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) { + // move target anchor if this is a target change. + if (moveType === 0 /* TARGET_CHANGE */) { + insert(vnode.targetAnchor, container, parentAnchor); + } + const { el, anchor, shapeFlag, children, props } = vnode; + const isReorder = moveType === 2 /* REORDER */; + // move main view anchor if this is a re-order. + if (isReorder) { + insert(el, container, parentAnchor); + } + // if this is a re-order and teleport is enabled (content is in target) + // do not move children. So the opposite is: only move children if this + // is not a reorder, or the teleport is disabled + if (!isReorder || isTeleportDisabled(props)) { + // Teleport has either Array children or no children. + if (shapeFlag & 16 /* ARRAY_CHILDREN */) { + for (let i = 0; i < children.length; i++) { + move(children[i], container, parentAnchor, 2 /* REORDER */); + } + } + } + // move main view anchor if this is a re-order. + if (isReorder) { + insert(anchor, container, parentAnchor); + } +} +function hydrateTeleport(node, vnode, parentComponent, parentSuspense, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) { + const target = (vnode.target = resolveTarget(vnode.props, querySelector)); + if (target) { + // if multiple teleports rendered to the same target element, we need to + // pick up from where the last teleport finished instead of the first node + const targetNode = target._lpa || target.firstChild; + if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) { + if (isTeleportDisabled(vnode.props)) { + vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, optimized); + vnode.targetAnchor = targetNode; + } + else { + vnode.anchor = nextSibling(node); + vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, optimized); + } + target._lpa = + vnode.targetAnchor && nextSibling(vnode.targetAnchor); + } + } + return vnode.anchor && nextSibling(vnode.anchor); +} +// Force-casted public typing for h and TSX props inference +const Teleport = TeleportImpl; -let devtools; -function setDevtoolsHook(hook) { - devtools = hook; -} -function devtoolsInitApp(app, version) { - // TODO queue if devtools is undefined - if (!devtools) return - devtools.emit('app:init' /* APP_INIT */, app, version, { - Fragment, - Text, - Comment, - Static - }); -} -function devtoolsUnmountApp(app) { - if (!devtools) return - devtools.emit('app:unmount' /* APP_UNMOUNT */, app); -} -const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook( - 'component:added' /* COMPONENT_ADDED */ -); -const devtoolsComponentUpdated = /*#__PURE__*/ createDevtoolsComponentHook( - 'component:updated' /* COMPONENT_UPDATED */ -); -const devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook( - 'component:removed' /* COMPONENT_REMOVED */ -); -function createDevtoolsComponentHook(hook) { - return component => { - if (!devtools) return - devtools.emit( - hook, - component.appContext.app, - component.uid, - component.parent ? component.parent.uid : undefined - ); - } -} -function devtoolsComponentEmit(component, event, params) { - if (!devtools) return - devtools.emit( - 'component:emit' /* COMPONENT_EMIT */, - component.appContext.app, - component, - event, - params - ); +const COMPONENTS = 'components'; +const DIRECTIVES = 'directives'; +/** + * @private + */ +function resolveComponent(name) { + return resolveAsset(COMPONENTS, name) || name; +} +const NULL_DYNAMIC_COMPONENT = Symbol(); +/** + * @private + */ +function resolveDynamicComponent(component) { + if (isString(component)) { + return resolveAsset(COMPONENTS, component, false) || component; + } + else { + // invalid types will fallthrough to createVNode and raise warning + return (component || NULL_DYNAMIC_COMPONENT); + } +} +/** + * @private + */ +function resolveDirective(name) { + return resolveAsset(DIRECTIVES, name); +} +// implementation +function resolveAsset(type, name, warnMissing = true) { + const instance = currentRenderingInstance || currentInstance; + if (instance) { + const Component = instance.type; + // self name has highest priority + if (type === COMPONENTS) { + const selfName = Component.displayName || Component.name; + if (selfName && + (selfName === name || + selfName === camelize(name) || + selfName === capitalize(camelize(name)))) { + return Component; + } + } + const res = + // local registration + // check instance[type] first for components with mixin or extends. + resolve(instance[type] || Component[type], name) || + // global registration + resolve(instance.appContext[type], name); + if ((process.env.NODE_ENV !== 'production') && warnMissing && !res) { + warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`); + } + return res; + } + else if ((process.env.NODE_ENV !== 'production')) { + warn(`resolve${capitalize(type.slice(0, -1))} ` + + `can only be used in render() or setup().`); + } +} +function resolve(registry, name) { + return (registry && + (registry[name] || + registry[camelize(name)] || + registry[capitalize(camelize(name))])); } -function emit(instance, event, ...args) { - const props = instance.vnode.props || EMPTY_OBJ; - if (process.env.NODE_ENV !== 'production') { - const { - emitsOptions, - propsOptions: [propsOptions] - } = instance; - if (emitsOptions) { - if (!(event in emitsOptions)) { - if (!propsOptions || !(`on` + capitalize(event) in propsOptions)) { - warn( - `Component emitted event "${event}" but it is neither declared in ` + - `the emits option nor as an "on${capitalize(event)}" prop.` - ); - } - } else { - const validator = emitsOptions[event]; - if (isFunction(validator)) { - const isValid = validator(...args); - if (!isValid) { - warn( - `Invalid event arguments: event validation failed for event "${event}".` - ); - } - } - } - } - } - if (process.env.NODE_ENV !== 'production' || __VUE_PROD_DEVTOOLS__) { - devtoolsComponentEmit(instance, event, args); - } - let handlerName = `on${capitalize(event)}`; - let handler = props[handlerName]; - // for v-model update:xxx events, also trigger kebab-case equivalent - // for props passed via kebab-case - if (!handler && event.startsWith('update:')) { - handlerName = `on${capitalize(hyphenate(event))}`; - handler = props[handlerName]; - } - if (!handler) { - handler = props[handlerName + `Once`]; - if (!instance.emitted) { -(instance.emitted = {})[handlerName] = true; - } else if (instance.emitted[handlerName]) { - return - } - } - if (handler) { - callWithAsyncErrorHandling( - handler, - instance, - 6 /* COMPONENT_EVENT_HANDLER */, - args - ); - } -} -function normalizeEmitsOptions(comp, appContext, asMixin = false) { - const appId = appContext.app ? appContext.app._uid : -1; - const cache = comp.__emits || (comp.__emits = {}); - const cached = cache[appId]; - if (cached !== undefined) { - return cached - } - const raw = comp.emits; - let normalized = {}; - // apply mixin/extends props - let hasExtends = false; - if (__VUE_OPTIONS_API__ && !isFunction(comp)) { - const extendEmits = raw => { - hasExtends = true; - extend(normalized, normalizeEmitsOptions(raw, appContext, true)); - }; - if (!asMixin && appContext.mixins.length) { - appContext.mixins.forEach(extendEmits); - } - if (comp.extends) { - extendEmits(comp.extends); - } - if (comp.mixins) { - comp.mixins.forEach(extendEmits); - } - } - if (!raw && !hasExtends) { - return (cache[appId] = null) - } - if (isArray(raw)) { - raw.forEach(key => (normalized[key] = null)); - } else { - extend(normalized, raw); - } - return (cache[appId] = normalized) -} -// Check if an incoming prop key is a declared emit event listener. -// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are -// both considered matched listeners. -function isEmitListener(options, key) { - if (!options || !isOn(key)) { - return false - } - key = key.replace(/Once$/, ''); - return ( - hasOwn(options, key[2].toLowerCase() + key.slice(3)) || - hasOwn(options, key.slice(2)) - ) +const Fragment = Symbol((process.env.NODE_ENV !== 'production') ? 'Fragment' : undefined); +const Text = Symbol((process.env.NODE_ENV !== 'production') ? 'Text' : undefined); +const Comment = Symbol((process.env.NODE_ENV !== 'production') ? 'Comment' : undefined); +const Static = Symbol((process.env.NODE_ENV !== 'production') ? 'Static' : undefined); +// Since v-if and v-for are the two possible ways node structure can dynamically +// change, once we consider v-if branches and each v-for fragment a block, we +// can divide a template into nested blocks, and within each block the node +// structure would be stable. This allows us to skip most children diffing +// and only worry about the dynamic nodes (indicated by patch flags). +const blockStack = []; +let currentBlock = null; +/** + * Open a block. + * This must be called before `createBlock`. It cannot be part of `createBlock` + * because the children of the block are evaluated before `createBlock` itself + * is called. The generated code typically looks like this: + * + * ```js + * function render() { + * return (openBlock(),createBlock('div', null, [...])) + * } + * ``` + * disableTracking is true when creating a v-for fragment block, since a v-for + * fragment always diffs its children. + * + * @private + */ +function openBlock(disableTracking = false) { + blockStack.push((currentBlock = disableTracking ? null : [])); +} +function closeBlock() { + blockStack.pop(); + currentBlock = blockStack[blockStack.length - 1] || null; +} +// Whether we should be tracking dynamic child nodes inside a block. +// Only tracks when this value is > 0 +// We are not using a simple boolean because this value may need to be +// incremented/decremented by nested usage of v-once (see below) +let shouldTrack$1 = 1; +/** + * Block tracking sometimes needs to be disabled, for example during the + * creation of a tree that needs to be cached by v-once. The compiler generates + * code like this: + * + * ``` js + * _cache[1] || ( + * setBlockTracking(-1), + * _cache[1] = createVNode(...), + * setBlockTracking(1), + * _cache[1] + * ) + * ``` + * + * @private + */ +function setBlockTracking(value) { + shouldTrack$1 += value; +} +/** + * Create a block root vnode. Takes the same exact arguments as `createVNode`. + * A block root keeps track of dynamic nodes within the block in the + * `dynamicChildren` array. + * + * @private + */ +function createBlock(type, props, children, patchFlag, dynamicProps) { + const vnode = createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */); + // save current block children on the block vnode + vnode.dynamicChildren = currentBlock || EMPTY_ARR; + // close block + closeBlock(); + // a block is always going to be patched, so track it as a child of its + // parent block + if (shouldTrack$1 > 0 && currentBlock) { + currentBlock.push(vnode); + } + return vnode; +} +function isVNode(value) { + return value ? value.__v_isVNode === true : false; +} +function isSameVNodeType(n1, n2) { + if ((process.env.NODE_ENV !== 'production') && + n2.shapeFlag & 6 /* COMPONENT */ && + hmrDirtyComponents.has(n2.type)) { + // HMR only: if the component has been hot-updated, force a reload. + return false; + } + return n1.type === n2.type && n1.key === n2.key; +} +let vnodeArgsTransformer; +/** + * Internal API for registering an arguments transform for createVNode + * used for creating stubs in the test-utils + * It is *internal* but needs to be exposed for test-utils to pick up proper + * typings + */ +function transformVNodeArgs(transformer) { + vnodeArgsTransformer = transformer; +} +const createVNodeWithArgsTransform = (...args) => { + return _createVNode(...(vnodeArgsTransformer + ? vnodeArgsTransformer(args, currentRenderingInstance) + : args)); +}; +const InternalObjectKey = `__vInternal`; +const normalizeKey = ({ key }) => key != null ? key : null; +const normalizeRef = ({ ref }) => { + return (ref != null + ? isArray(ref) + ? ref + : { i: currentRenderingInstance, r: ref } + : null); +}; +const createVNode = ((process.env.NODE_ENV !== 'production') + ? createVNodeWithArgsTransform + : _createVNode); +function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) { + if (!type || type === NULL_DYNAMIC_COMPONENT) { + if ((process.env.NODE_ENV !== 'production') && !type) { + warn(`Invalid vnode type when creating vnode: ${type}.`); + } + type = Comment; + } + if (isVNode(type)) { + // createVNode receiving an existing vnode. This happens in cases like + // + // #2078 make sure to merge refs during the clone instead of overwriting it + const cloned = cloneVNode(type, props, true /* mergeRef: true */); + if (children) { + normalizeChildren(cloned, children); + } + return cloned; + } + // class component normalization. + if (isClassComponent(type)) { + type = type.__vccOpts; + } + // class & style normalization. + if (props) { + // for reactive or proxy objects, we need to clone it to enable mutation. + if (isProxy(props) || InternalObjectKey in props) { + props = extend({}, props); + } + let { class: klass, style } = props; + if (klass && !isString(klass)) { + props.class = normalizeClass(klass); + } + if (isObject(style)) { + // reactive state objects need to be cloned since they are likely to be + // mutated + if (isProxy(style) && !isArray(style)) { + style = extend({}, style); + } + props.style = normalizeStyle(style); + } + } + // encode the vnode type information into a bitmap + const shapeFlag = isString(type) + ? 1 /* ELEMENT */ + : isSuspense(type) + ? 128 /* SUSPENSE */ + : isTeleport(type) + ? 64 /* TELEPORT */ + : isObject(type) + ? 4 /* STATEFUL_COMPONENT */ + : isFunction(type) + ? 2 /* FUNCTIONAL_COMPONENT */ + : 0; + if ((process.env.NODE_ENV !== 'production') && shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) { + type = toRaw(type); + warn(`Vue received a Component which was made a reactive object. This can ` + + `lead to unnecessary performance overhead, and should be avoided by ` + + `marking the component with \`markRaw\` or using \`shallowRef\` ` + + `instead of \`ref\`.`, `\nComponent that was made reactive: `, type); + } + const vnode = { + __v_isVNode: true, + ["__v_skip" /* SKIP */]: true, + type, + props, + key: props && normalizeKey(props), + ref: props && normalizeRef(props), + scopeId: currentScopeId, + children: null, + component: null, + suspense: null, + ssContent: null, + ssFallback: null, + dirs: null, + transition: null, + el: null, + anchor: null, + target: null, + targetAnchor: null, + staticCount: 0, + shapeFlag, + patchFlag, + dynamicProps, + dynamicChildren: null, + appContext: null + }; + // validate key + if ((process.env.NODE_ENV !== 'production') && vnode.key !== vnode.key) { + warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type); + } + normalizeChildren(vnode, children); + // normalize suspense children + if ( shapeFlag & 128 /* SUSPENSE */) { + const { content, fallback } = normalizeSuspenseChildren(vnode); + vnode.ssContent = content; + vnode.ssFallback = fallback; + } + if (shouldTrack$1 > 0 && + // avoid a block node from tracking itself + !isBlockNode && + // has current parent block + currentBlock && + // presence of a patch flag indicates this node needs patching on updates. + // component nodes also should always be patched, because even if the + // component doesn't need to update, it needs to persist the instance on to + // the next vnode so that it can be properly unmounted later. + (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) && + // the EVENTS flag is only for hydration and if it is the only flag, the + // vnode should not be considered dynamic due to handler caching. + patchFlag !== 32 /* HYDRATE_EVENTS */) { + currentBlock.push(vnode); + } + return vnode; +} +function cloneVNode(vnode, extraProps, mergeRef = false) { + // This is intentionally NOT using spread or extend to avoid the runtime + // key enumeration cost. + const { props, ref, patchFlag } = vnode; + const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props; + return { + __v_isVNode: true, + ["__v_skip" /* SKIP */]: true, + type: vnode.type, + props: mergedProps, + key: mergedProps && normalizeKey(mergedProps), + ref: extraProps && extraProps.ref + ? // #2078 in the case of + // if the vnode itself already has a ref, cloneVNode will need to merge + // the refs so the single vnode can be set on multiple refs + mergeRef && ref + ? isArray(ref) + ? ref.concat(normalizeRef(extraProps)) + : [ref, normalizeRef(extraProps)] + : normalizeRef(extraProps) + : ref, + scopeId: vnode.scopeId, + children: vnode.children, + target: vnode.target, + targetAnchor: vnode.targetAnchor, + staticCount: vnode.staticCount, + shapeFlag: vnode.shapeFlag, + // if the vnode is cloned with extra props, we can no longer assume its + // existing patch flag to be reliable and need to add the FULL_PROPS flag. + // note: perserve flag for fragments since they use the flag for children + // fast paths only. + patchFlag: extraProps && vnode.type !== Fragment + ? patchFlag === -1 // hoisted node + ? 16 /* FULL_PROPS */ + : patchFlag | 16 /* FULL_PROPS */ + : patchFlag, + dynamicProps: vnode.dynamicProps, + dynamicChildren: vnode.dynamicChildren, + appContext: vnode.appContext, + dirs: vnode.dirs, + transition: vnode.transition, + // These should technically only be non-null on mounted VNodes. However, + // they *should* be copied for kept-alive vnodes. So we just always copy + // them since them being non-null during a mount doesn't affect the logic as + // they will simply be overwritten. + component: vnode.component, + suspense: vnode.suspense, + ssContent: vnode.ssContent && cloneVNode(vnode.ssContent), + ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback), + el: vnode.el, + anchor: vnode.anchor + }; +} +/** + * @private + */ +function createTextVNode(text = ' ', flag = 0) { + return createVNode(Text, null, text, flag); +} +/** + * @private + */ +function createStaticVNode(content, numberOfNodes) { + // A static vnode can contain multiple stringified elements, and the number + // of elements is necessary for hydration. + const vnode = createVNode(Static, null, content); + vnode.staticCount = numberOfNodes; + return vnode; +} +/** + * @private + */ +function createCommentVNode(text = '', +// when used as the v-else branch, the comment node must be created as a +// block to ensure correct updates. +asBlock = false) { + return asBlock + ? (openBlock(), createBlock(Comment, null, text)) + : createVNode(Comment, null, text); +} +function normalizeVNode(child) { + if (child == null || typeof child === 'boolean') { + // empty placeholder + return createVNode(Comment); + } + else if (isArray(child)) { + // fragment + return createVNode(Fragment, null, child); + } + else if (typeof child === 'object') { + // already vnode, this should be the most common since compiled templates + // always produce all-vnode children arrays + return child.el === null ? child : cloneVNode(child); + } + else { + // strings and numbers + return createVNode(Text, null, String(child)); + } +} +// optimized normalization for template-compiled render fns +function cloneIfMounted(child) { + return child.el === null ? child : cloneVNode(child); +} +function normalizeChildren(vnode, children) { + let type = 0; + const { shapeFlag } = vnode; + if (children == null) { + children = null; + } + else if (isArray(children)) { + type = 16 /* ARRAY_CHILDREN */; + } + else if (typeof children === 'object') { + if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 64 /* TELEPORT */) { + // Normalize slot to plain children for plain element and Teleport + const slot = children.default; + if (slot) { + // _c marker is added by withCtx() indicating this is a compiled slot + slot._c && setCompiledSlotRendering(1); + normalizeChildren(vnode, slot()); + slot._c && setCompiledSlotRendering(-1); + } + return; + } + else { + type = 32 /* SLOTS_CHILDREN */; + const slotFlag = children._; + if (!slotFlag && !(InternalObjectKey in children)) { + children._ctx = currentRenderingInstance; + } + else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) { + // a child component receives forwarded slots from the parent. + // its slot type is determined by its parent's slot type. + if (currentRenderingInstance.vnode.patchFlag & 1024 /* DYNAMIC_SLOTS */) { + children._ = 2 /* DYNAMIC */; + vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */; + } + else { + children._ = 1 /* STABLE */; + } + } + } + } + else if (isFunction(children)) { + children = { default: children, _ctx: currentRenderingInstance }; + type = 32 /* SLOTS_CHILDREN */; + } + else { + children = String(children); + // force teleport children to array so it can be moved around + if (shapeFlag & 64 /* TELEPORT */) { + type = 16 /* ARRAY_CHILDREN */; + children = [createTextVNode(children)]; + } + else { + type = 8 /* TEXT_CHILDREN */; + } + } + vnode.children = children; + vnode.shapeFlag |= type; +} +function mergeProps(...args) { + const ret = extend({}, args[0]); + for (let i = 1; i < args.length; i++) { + const toMerge = args[i]; + for (const key in toMerge) { + if (key === 'class') { + if (ret.class !== toMerge.class) { + ret.class = normalizeClass([ret.class, toMerge.class]); + } + } + else if (key === 'style') { + ret.style = normalizeStyle([ret.style, toMerge.style]); + } + else if (isOn(key)) { + const existing = ret[key]; + const incoming = toMerge[key]; + if (existing !== incoming) { + ret[key] = existing + ? [].concat(existing, toMerge[key]) + : incoming; + } + } + else { + ret[key] = toMerge[key]; + } + } + } + return ret; } -function initProps( - instance, - rawProps, - isStateful, // result of bitwise flag comparison - isSSR = false -) { - const props = {}; - const attrs = {}; - def(attrs, InternalObjectKey, 1); - setFullProps(instance, rawProps, props, attrs); - // validation - if (process.env.NODE_ENV !== 'production') { - validateProps(props, instance); - } - if (isStateful) { - // stateful - instance.props = isSSR ? props : shallowReactive(props); - } else { - if (!instance.type.props) { - // functional w/ optional props, props === attrs - instance.props = attrs; - } else { - // functional w/ declared props - instance.props = props; - } - } - instance.attrs = attrs; -} -function updateProps(instance, rawProps, rawPrevProps, optimized) { - const { - props, - attrs, - vnode: { patchFlag } - } = instance; - const rawCurrentProps = toRaw(props); - const [options] = instance.propsOptions; - if ( - // always force full diff if hmr is enabled - !(process.env.NODE_ENV !== 'production' && instance.type.__hmrId) && - (optimized || patchFlag > 0) && - !(patchFlag & 16) /* FULL_PROPS */ - ) { - if (patchFlag & 8 /* PROPS */) { - // Compiler-generated props & no keys change, just set the updated - // the props. - const propsToUpdate = instance.vnode.dynamicProps; - for (let i = 0; i < propsToUpdate.length; i++) { - const key = propsToUpdate[i]; - // PROPS flag guarantees rawProps to be non-null - const value = rawProps[key]; - if (options) { - // attr / props separation was done on init and will be consistent - // in this code path, so just check if attrs have it. - if (hasOwn(attrs, key)) { - attrs[key] = value; - } else { - const camelizedKey = camelize(key); - props[camelizedKey] = resolvePropValue( - options, - rawCurrentProps, - camelizedKey, - value - ); - } - } else { - attrs[key] = value; - } - } - } - } else { - // full props update. - setFullProps(instance, rawProps, props, attrs); - // in case of dynamic props, check if we need to delete keys from - // the props object - let kebabKey; - for (const key in rawCurrentProps) { - if ( - !rawProps || - // for camelCase - (!hasOwn(rawProps, key) && - // it's possible the original props was passed in as kebab-case - // and converted to camelCase (#955) - ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey))) - ) { - if (options) { - if ( - rawPrevProps && - // for camelCase - (rawPrevProps[key] !== undefined || - // for kebab-case - rawPrevProps[kebabKey] !== undefined) - ) { - props[key] = resolvePropValue( - options, - rawProps || EMPTY_OBJ, - key, - undefined - ); - } - } else { - delete props[key]; - } - } - } - // in the case of functional component w/o props declaration, props and - // attrs point to the same object so it should already have been updated. - if (attrs !== rawCurrentProps) { - for (const key in attrs) { - if (!rawProps || !hasOwn(rawProps, key)) { - delete attrs[key]; - } - } - } - } - // trigger updates for $attrs in case it's used in component slots - trigger(instance, 'set' /* SET */, '$attrs'); - if (process.env.NODE_ENV !== 'production' && rawProps) { - validateProps(props, instance); - } -} -function setFullProps(instance, rawProps, props, attrs) { - const [options, needCastKeys] = instance.propsOptions; - if (rawProps) { - for (const key in rawProps) { - const value = rawProps[key]; - // key, ref are reserved and never passed down - if (isReservedProp(key)) { - continue - } - // prop option names are camelized during normalization, so to support - // kebab -> camel conversion here we need to camelize the key. - let camelKey; - if (options && hasOwn(options, (camelKey = camelize(key)))) { - props[camelKey] = value; - } else if (!isEmitListener(instance.emitsOptions, key)) { - // Any non-declared (either as a prop or an emitted event) props are put - // into a separate `attrs` object for spreading. Make sure to preserve - // original key casing - attrs[key] = value; - } - } - } - if (needCastKeys) { - const rawCurrentProps = toRaw(props); - for (let i = 0; i < needCastKeys.length; i++) { - const key = needCastKeys[i]; - props[key] = resolvePropValue( - options, - rawCurrentProps, - key, - rawCurrentProps[key] - ); - } - } -} -function resolvePropValue(options, props, key, value) { - const opt = options[key]; - if (opt != null) { - const hasDefault = hasOwn(opt, 'default'); - // default values - if (hasDefault && value === undefined) { - const defaultValue = opt.default; - value = - opt.type !== Function && isFunction(defaultValue) - ? defaultValue(props) - : defaultValue; - } - // boolean casting - if (opt[0 /* shouldCast */]) { - if (!hasOwn(props, key) && !hasDefault) { - value = false; - } else if ( - opt[1 /* shouldCastTrue */] && - (value === '' || value === hyphenate(key)) - ) { - value = true; - } - } - } - return value -} -function normalizePropsOptions(comp, appContext, asMixin = false) { - const appId = appContext.app ? appContext.app._uid : -1; - const cache = comp.__props || (comp.__props = {}); - const cached = cache[appId]; - if (cached) { - return cached - } - const raw = comp.props; - const normalized = {}; - const needCastKeys = []; - // apply mixin/extends props - let hasExtends = false; - if (__VUE_OPTIONS_API__ && !isFunction(comp)) { - const extendProps = raw => { - hasExtends = true; - const [props, keys] = normalizePropsOptions(raw, appContext, true); - extend(normalized, props); - if (keys) needCastKeys.push(...keys); - }; - if (!asMixin && appContext.mixins.length) { - appContext.mixins.forEach(extendProps); - } - if (comp.extends) { - extendProps(comp.extends); - } - if (comp.mixins) { - comp.mixins.forEach(extendProps); - } - } - if (!raw && !hasExtends) { - return (cache[appId] = EMPTY_ARR) - } - if (isArray(raw)) { - for (let i = 0; i < raw.length; i++) { - if (process.env.NODE_ENV !== 'production' && !isString(raw[i])) { - warn(`props must be strings when using array syntax.`, raw[i]); - } - const normalizedKey = camelize(raw[i]); - if (validatePropName(normalizedKey)) { - normalized[normalizedKey] = EMPTY_OBJ; - } - } - } else if (raw) { - if (process.env.NODE_ENV !== 'production' && !isObject(raw)) { - warn(`invalid props options`, raw); - } - for (const key in raw) { - const normalizedKey = camelize(key); - if (validatePropName(normalizedKey)) { - const opt = raw[key]; - const prop = (normalized[normalizedKey] = - isArray(opt) || isFunction(opt) ? { type: opt } : opt); - if (prop) { - const booleanIndex = getTypeIndex(Boolean, prop.type); - const stringIndex = getTypeIndex(String, prop.type); - prop[0 /* shouldCast */] = booleanIndex > -1; - prop[1 /* shouldCastTrue */] = - stringIndex < 0 || booleanIndex < stringIndex; - // if the prop needs boolean casting or default value - if (booleanIndex > -1 || hasOwn(prop, 'default')) { - needCastKeys.push(normalizedKey); - } - } - } - } - } - return (cache[appId] = [normalized, needCastKeys]) -} -// use function string name to check type constructors -// so that it works across vms / iframes. -function getType(ctor) { - const match = ctor && ctor.toString().match(/^\s*function (\w+)/); - return match ? match[1] : '' -} -function isSameType(a, b) { - return getType(a) === getType(b) -} -function getTypeIndex(type, expectedTypes) { - if (isArray(expectedTypes)) { - for (let i = 0, len = expectedTypes.length; i < len; i++) { - if (isSameType(expectedTypes[i], type)) { - return i - } - } - } else if (isFunction(expectedTypes)) { - return isSameType(expectedTypes, type) ? 0 : -1 - } - return -1 -} -/** - * dev only - */ -function validateProps(props, instance) { - const rawValues = toRaw(props); - const options = instance.propsOptions[0]; - for (const key in options) { - let opt = options[key]; - if (opt == null) continue - validateProp(key, rawValues[key], opt, !hasOwn(rawValues, key)); - } -} -/** - * dev only - */ -function validatePropName(key) { - if (key[0] !== '$') { - return true - } else if (process.env.NODE_ENV !== 'production') { - warn(`Invalid prop name: "${key}" is a reserved property.`); - } - return false -} -/** - * dev only - */ -function validateProp(name, value, prop, isAbsent) { - const { type, required, validator } = prop; - // required! - if (required && isAbsent) { - warn('Missing required prop: "' + name + '"'); - return - } - // missing but optional - if (value == null && !prop.required) { - return - } - // type check - if (type != null && type !== true) { - let isValid = false; - const types = isArray(type) ? type : [type]; - const expectedTypes = []; - // value is valid as long as one of the specified types match - for (let i = 0; i < types.length && !isValid; i++) { - const { valid, expectedType } = assertType(value, types[i]); - expectedTypes.push(expectedType || ''); - isValid = valid; - } - if (!isValid) { - warn(getInvalidTypeMessage(name, value, expectedTypes)); - return - } - } - // custom validator - if (validator && !validator(value)) { - warn('Invalid prop: custom validator check failed for prop "' + name + '".'); - } -} -const isSimpleType = /*#__PURE__*/ makeMap( - 'String,Number,Boolean,Function,Symbol' -); -/** - * dev only - */ -function assertType(value, type) { - let valid; - const expectedType = getType(type); - if (isSimpleType(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 = isObject(value); - } else if (expectedType === 'Array') { - valid = isArray(value); - } else { - valid = value instanceof type; - } - return { - valid, - expectedType - } -} -/** - * dev only - */ -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 -} -/** - * dev only - */ -function styleValue(value, type) { - if (type === 'String') { - return `"${value}"` - } else if (type === 'Number') { - return `${Number(value)}` - } else { - return `${value}` - } -} -/** - * dev only - */ -function isExplicable(type) { - const explicitTypes = ['string', 'number', 'boolean']; - return explicitTypes.some(elem => type.toLowerCase() === elem) -} -/** - * dev only - */ -function isBoolean(...args) { - return args.some(elem => elem.toLowerCase() === 'boolean') +function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison +isSSR = false) { + const props = {}; + const attrs = {}; + def(attrs, InternalObjectKey, 1); + setFullProps(instance, rawProps, props, attrs); + // validation + if ((process.env.NODE_ENV !== 'production')) { + validateProps(props, instance); + } + if (isStateful) { + // stateful + instance.props = isSSR ? props : shallowReactive(props); + } + else { + if (!instance.type.props) { + // functional w/ optional props, props === attrs + instance.props = attrs; + } + else { + // functional w/ declared props + instance.props = props; + } + } + instance.attrs = attrs; +} +function updateProps(instance, rawProps, rawPrevProps, optimized) { + const { props, attrs, vnode: { patchFlag } } = instance; + const rawCurrentProps = toRaw(props); + const [options] = instance.propsOptions; + if ( + // always force full diff if hmr is enabled + !((process.env.NODE_ENV !== 'production') && instance.type.__hmrId) && + (optimized || patchFlag > 0) && + !(patchFlag & 16 /* FULL_PROPS */)) { + if (patchFlag & 8 /* PROPS */) { + // Compiler-generated props & no keys change, just set the updated + // the props. + const propsToUpdate = instance.vnode.dynamicProps; + for (let i = 0; i < propsToUpdate.length; i++) { + const key = propsToUpdate[i]; + // PROPS flag guarantees rawProps to be non-null + const value = rawProps[key]; + if (options) { + // attr / props separation was done on init and will be consistent + // in this code path, so just check if attrs have it. + if (hasOwn(attrs, key)) { + attrs[key] = value; + } + else { + const camelizedKey = camelize(key); + props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance); + } + } + else { + attrs[key] = value; + } + } + } + } + else { + // full props update. + setFullProps(instance, rawProps, props, attrs); + // in case of dynamic props, check if we need to delete keys from + // the props object + let kebabKey; + for (const key in rawCurrentProps) { + if (!rawProps || + // for camelCase + (!hasOwn(rawProps, key) && + // it's possible the original props was passed in as kebab-case + // and converted to camelCase (#955) + ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) { + if (options) { + if (rawPrevProps && + // for camelCase + (rawPrevProps[key] !== undefined || + // for kebab-case + rawPrevProps[kebabKey] !== undefined)) { + props[key] = resolvePropValue(options, rawProps || EMPTY_OBJ, key, undefined, instance); + } + } + else { + delete props[key]; + } + } + } + // in the case of functional component w/o props declaration, props and + // attrs point to the same object so it should already have been updated. + if (attrs !== rawCurrentProps) { + for (const key in attrs) { + if (!rawProps || !hasOwn(rawProps, key)) { + delete attrs[key]; + } + } + } + } + // trigger updates for $attrs in case it's used in component slots + trigger(instance, "set" /* SET */, '$attrs'); + if ((process.env.NODE_ENV !== 'production') && rawProps) { + validateProps(props, instance); + } +} +function setFullProps(instance, rawProps, props, attrs) { + const [options, needCastKeys] = instance.propsOptions; + if (rawProps) { + for (const key in rawProps) { + const value = rawProps[key]; + // key, ref are reserved and never passed down + if (isReservedProp(key)) { + continue; + } + // prop option names are camelized during normalization, so to support + // kebab -> camel conversion here we need to camelize the key. + let camelKey; + if (options && hasOwn(options, (camelKey = camelize(key)))) { + props[camelKey] = value; + } + else if (!isEmitListener(instance.emitsOptions, key)) { + // Any non-declared (either as a prop or an emitted event) props are put + // into a separate `attrs` object for spreading. Make sure to preserve + // original key casing + attrs[key] = value; + } + } + } + if (needCastKeys) { + const rawCurrentProps = toRaw(props); + for (let i = 0; i < needCastKeys.length; i++) { + const key = needCastKeys[i]; + props[key] = resolvePropValue(options, rawCurrentProps, key, rawCurrentProps[key], instance); + } + } +} +function resolvePropValue(options, props, key, value, instance) { + const opt = options[key]; + if (opt != null) { + const hasDefault = hasOwn(opt, 'default'); + // default values + if (hasDefault && value === undefined) { + const defaultValue = opt.default; + if (opt.type !== Function && isFunction(defaultValue)) { + setCurrentInstance(instance); + value = defaultValue(props); + setCurrentInstance(null); + } + else { + value = defaultValue; + } + } + // boolean casting + if (opt[0 /* shouldCast */]) { + if (!hasOwn(props, key) && !hasDefault) { + value = false; + } + else if (opt[1 /* shouldCastTrue */] && + (value === '' || value === hyphenate(key))) { + value = true; + } + } + } + return value; +} +function normalizePropsOptions(comp, appContext, asMixin = false) { + const appId = appContext.app ? appContext.app._uid : -1; + const cache = comp.__props || (comp.__props = {}); + const cached = cache[appId]; + if (cached) { + return cached; + } + const raw = comp.props; + const normalized = {}; + const needCastKeys = []; + // apply mixin/extends props + let hasExtends = false; + if (__VUE_OPTIONS_API__ && !isFunction(comp)) { + const extendProps = (raw) => { + hasExtends = true; + const [props, keys] = normalizePropsOptions(raw, appContext, true); + extend(normalized, props); + if (keys) + needCastKeys.push(...keys); + }; + if (!asMixin && appContext.mixins.length) { + appContext.mixins.forEach(extendProps); + } + if (comp.extends) { + extendProps(comp.extends); + } + if (comp.mixins) { + comp.mixins.forEach(extendProps); + } + } + if (!raw && !hasExtends) { + return (cache[appId] = EMPTY_ARR); + } + if (isArray(raw)) { + for (let i = 0; i < raw.length; i++) { + if ((process.env.NODE_ENV !== 'production') && !isString(raw[i])) { + warn(`props must be strings when using array syntax.`, raw[i]); + } + const normalizedKey = camelize(raw[i]); + if (validatePropName(normalizedKey)) { + normalized[normalizedKey] = EMPTY_OBJ; + } + } + } + else if (raw) { + if ((process.env.NODE_ENV !== 'production') && !isObject(raw)) { + warn(`invalid props options`, raw); + } + for (const key in raw) { + const normalizedKey = camelize(key); + if (validatePropName(normalizedKey)) { + const opt = raw[key]; + const prop = (normalized[normalizedKey] = + isArray(opt) || isFunction(opt) ? { type: opt } : opt); + if (prop) { + const booleanIndex = getTypeIndex(Boolean, prop.type); + const stringIndex = getTypeIndex(String, prop.type); + prop[0 /* shouldCast */] = booleanIndex > -1; + prop[1 /* shouldCastTrue */] = + stringIndex < 0 || booleanIndex < stringIndex; + // if the prop needs boolean casting or default value + if (booleanIndex > -1 || hasOwn(prop, 'default')) { + needCastKeys.push(normalizedKey); + } + } + } + } + } + return (cache[appId] = [normalized, needCastKeys]); +} +// use function string name to check type constructors +// so that it works across vms / iframes. +function getType(ctor) { + const match = ctor && ctor.toString().match(/^\s*function (\w+)/); + return match ? match[1] : ''; +} +function isSameType(a, b) { + return getType(a) === getType(b); +} +function getTypeIndex(type, expectedTypes) { + if (isArray(expectedTypes)) { + for (let i = 0, len = expectedTypes.length; i < len; i++) { + if (isSameType(expectedTypes[i], type)) { + return i; + } + } + } + else if (isFunction(expectedTypes)) { + return isSameType(expectedTypes, type) ? 0 : -1; + } + return -1; +} +/** + * dev only + */ +function validateProps(props, instance) { + const rawValues = toRaw(props); + const options = instance.propsOptions[0]; + for (const key in options) { + let opt = options[key]; + if (opt == null) + continue; + validateProp(key, rawValues[key], opt, !hasOwn(rawValues, key)); + } +} +/** + * dev only + */ +function validatePropName(key) { + if (key[0] !== '$') { + return true; + } + else if ((process.env.NODE_ENV !== 'production')) { + warn(`Invalid prop name: "${key}" is a reserved property.`); + } + return false; +} +/** + * dev only + */ +function validateProp(name, value, prop, isAbsent) { + const { type, required, validator } = prop; + // required! + if (required && isAbsent) { + warn('Missing required prop: "' + name + '"'); + return; + } + // missing but optional + if (value == null && !prop.required) { + return; + } + // type check + if (type != null && type !== true) { + let isValid = false; + const types = isArray(type) ? type : [type]; + const expectedTypes = []; + // value is valid as long as one of the specified types match + for (let i = 0; i < types.length && !isValid; i++) { + const { valid, expectedType } = assertType(value, types[i]); + expectedTypes.push(expectedType || ''); + isValid = valid; + } + if (!isValid) { + warn(getInvalidTypeMessage(name, value, expectedTypes)); + return; + } + } + // custom validator + if (validator && !validator(value)) { + warn('Invalid prop: custom validator check failed for prop "' + name + '".'); + } +} +const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol'); +/** + * dev only + */ +function assertType(value, type) { + let valid; + const expectedType = getType(type); + if (isSimpleType(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 = isObject(value); + } + else if (expectedType === 'Array') { + valid = isArray(value); + } + else { + valid = value instanceof type; + } + return { + valid, + expectedType + }; +} +/** + * dev only + */ +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; +} +/** + * dev only + */ +function styleValue(value, type) { + if (type === 'String') { + return `"${value}"`; + } + else if (type === 'Number') { + return `${Number(value)}`; + } + else { + return `${value}`; + } +} +/** + * dev only + */ +function isExplicable(type) { + const explicitTypes = ['string', 'number', 'boolean']; + return explicitTypes.some(elem => type.toLowerCase() === elem); +} +/** + * dev only + */ +function isBoolean(...args) { + return args.some(elem => elem.toLowerCase() === 'boolean'); } -function injectHook(type, hook, target = currentInstance, prepend = false) { - if (target) { - const hooks = target[type] || (target[type] = []); - // cache the error handling wrapper for injected hooks so the same hook - // can be properly deduped by the scheduler. "__weh" stands for "with error - // handling". - const wrappedHook = - hook.__weh || - (hook.__weh = (...args) => { - if (target.isUnmounted) { - return - } - // disable tracking inside all lifecycle hooks - // since they can potentially be called inside effects. - pauseTracking(); - // Set currentInstance during hook invocation. - // This assumes the hook does not synchronously trigger other hooks, which - // can only be false when the user does something really funky. - setCurrentInstance(target); - const res = callWithAsyncErrorHandling(hook, target, type, args); - setCurrentInstance(null); - resetTracking(); - return res - }); - if (prepend) { - hooks.unshift(wrappedHook); - } else { - hooks.push(wrappedHook); - } - return wrappedHook - } else if (process.env.NODE_ENV !== 'production') { - const apiName = `on${capitalize( - ErrorTypeStrings[type].replace(/ hook$/, '') - )}`; - warn( - `${apiName} is called when there is no active component instance to be ` + - `associated with. ` + - `Lifecycle injection APIs can only be used during execution of setup().` + - (` If you are using async setup(), make sure to register lifecycle ` + - `hooks before the first await statement.`) - ); - } -} -const createHook = lifecycle => (hook, target = currentInstance) => - // post-create lifecycle registrations are noops during SSR - !isInSSRComponentSetup && injectHook(lifecycle, hook, target); -const onBeforeMount = createHook('bm' /* BEFORE_MOUNT */); -const onMounted = createHook('m' /* MOUNTED */); -const onBeforeUpdate = createHook('bu' /* BEFORE_UPDATE */); -const onUpdated = createHook('u' /* UPDATED */); -const onBeforeUnmount = createHook('bum' /* BEFORE_UNMOUNT */); -const onUnmounted = createHook('um' /* UNMOUNTED */); -const onRenderTriggered = createHook('rtg' /* RENDER_TRIGGERED */); -const onRenderTracked = createHook('rtc' /* RENDER_TRACKED */); -const onErrorCaptured = (hook, target = currentInstance) => { - injectHook('ec' /* ERROR_CAPTURED */, hook, target); +function injectHook(type, hook, target = currentInstance, prepend = false) { + if (target) { + const hooks = target[type] || (target[type] = []); + // cache the error handling wrapper for injected hooks so the same hook + // can be properly deduped by the scheduler. "__weh" stands for "with error + // handling". + const wrappedHook = hook.__weh || + (hook.__weh = (...args) => { + if (target.isUnmounted) { + return; + } + // disable tracking inside all lifecycle hooks + // since they can potentially be called inside effects. + pauseTracking(); + // Set currentInstance during hook invocation. + // This assumes the hook does not synchronously trigger other hooks, which + // can only be false when the user does something really funky. + setCurrentInstance(target); + const res = callWithAsyncErrorHandling(hook, target, type, args); + setCurrentInstance(null); + resetTracking(); + return res; + }); + if (prepend) { + hooks.unshift(wrappedHook); + } + else { + hooks.push(wrappedHook); + } + return wrappedHook; + } + else if ((process.env.NODE_ENV !== 'production')) { + const apiName = `on${capitalize(ErrorTypeStrings[type].replace(/ hook$/, ''))}`; + warn(`${apiName} is called when there is no active component instance to be ` + + `associated with. ` + + `Lifecycle injection APIs can only be used during execution of setup().` + + ( ` If you are using async setup(), make sure to register lifecycle ` + + `hooks before the first await statement.` + )); + } +} +const createHook = (lifecycle) => (hook, target = currentInstance) => +// post-create lifecycle registrations are noops during SSR +!isInSSRComponentSetup && injectHook(lifecycle, hook, target); +const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */); +const onMounted = createHook("m" /* MOUNTED */); +const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */); +const onUpdated = createHook("u" /* UPDATED */); +const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */); +const onUnmounted = createHook("um" /* UNMOUNTED */); +const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */); +const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */); +const onErrorCaptured = (hook, target = currentInstance) => { + injectHook("ec" /* ERROR_CAPTURED */, hook, target); }; -function useTransitionState() { - const state = { - isMounted: false, - isLeaving: false, - isUnmounting: false, - leavingVNodes: new Map() - }; - onMounted(() => { - state.isMounted = true; - }); - onBeforeUnmount(() => { - state.isUnmounting = true; - }); - return state -} -const TransitionHookValidator = [Function, Array]; -const BaseTransitionImpl = { - name: `BaseTransition`, - props: { - mode: String, - appear: Boolean, - persisted: Boolean, - // enter - onBeforeEnter: TransitionHookValidator, - onEnter: TransitionHookValidator, - onAfterEnter: TransitionHookValidator, - onEnterCancelled: TransitionHookValidator, - // leave - onBeforeLeave: TransitionHookValidator, - onLeave: TransitionHookValidator, - onAfterLeave: TransitionHookValidator, - onLeaveCancelled: TransitionHookValidator, - // appear - onBeforeAppear: TransitionHookValidator, - onAppear: TransitionHookValidator, - onAfterAppear: TransitionHookValidator, - onAppearCancelled: TransitionHookValidator - }, - setup(props, { slots }) { - const instance = getCurrentInstance(); - const state = useTransitionState(); - let prevTransitionKey; - return () => { - const children = - slots.default && getTransitionRawChildren(slots.default(), true); - if (!children || !children.length) { - return - } - // warn multiple elements - if (process.env.NODE_ENV !== 'production' && children.length > 1) { - warn( - ' can only be used on a single element or component. Use ' + - ' for lists.' - ); - } - // there's no need to track reactivity for these props so use the raw - // props for a bit better perf - const rawProps = toRaw(props); - const { mode } = rawProps; - // check mode - if ( - process.env.NODE_ENV !== 'production' && - mode && - !['in-out', 'out-in', 'default'].includes(mode) - ) { - warn(`invalid mode: ${mode}`); - } - // at this point children has a guaranteed length of 1. - const child = children[0]; - if (state.isLeaving) { - return emptyPlaceholder(child) - } - // in the case of , we need to - // compare the type of the kept-alive children. - const innerChild = getKeepAliveChild(child); - if (!innerChild) { - return emptyPlaceholder(child) - } - const enterHooks = (innerChild.transition = resolveTransitionHooks( - innerChild, - rawProps, - state, - instance - )); - const oldChild = instance.subTree; - const oldInnerChild = oldChild && getKeepAliveChild(oldChild); - let transitionKeyChanged = false; - const { getTransitionKey } = innerChild.type; - if (getTransitionKey) { - const key = getTransitionKey(); - if (prevTransitionKey === undefined) { - prevTransitionKey = key; - } else if (key !== prevTransitionKey) { - prevTransitionKey = key; - transitionKeyChanged = true; - } - } - // handle mode - if ( - oldInnerChild && - oldInnerChild.type !== Comment && - (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged) - ) { - const leavingHooks = resolveTransitionHooks( - oldInnerChild, - rawProps, - state, - instance - ); - // update old tree's hooks in case of dynamic transition - setTransitionHooks(oldInnerChild, leavingHooks); - // switching between different views - if (mode === 'out-in') { - state.isLeaving = true; - // return placeholder node and queue update when leave finishes - leavingHooks.afterLeave = () => { - state.isLeaving = false; - instance.update(); - }; - return emptyPlaceholder(child) - } else if (mode === 'in-out') { - leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => { - const leavingVNodesCache = getLeavingNodesForType( - state, - oldInnerChild - ); - leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild; - // early removal callback - el._leaveCb = () => { - earlyRemove(); - el._leaveCb = undefined; - delete enterHooks.delayedLeave; - }; - enterHooks.delayedLeave = delayedLeave; - }; - } - } - return child - } - } -}; -// export the public type for h/tsx inference -// also to avoid inline import() in generated d.ts files -const BaseTransition = BaseTransitionImpl; -function getLeavingNodesForType(state, vnode) { - const { leavingVNodes } = state; - let leavingVNodesCache = leavingVNodes.get(vnode.type); - if (!leavingVNodesCache) { - leavingVNodesCache = Object.create(null); - leavingVNodes.set(vnode.type, leavingVNodesCache); - } - return leavingVNodesCache -} -// The transition hooks are attached to the vnode as vnode.transition -// and will be called at appropriate timing in the renderer. -function resolveTransitionHooks( - vnode, - { - appear, - persisted = false, - onBeforeEnter, - onEnter, - onAfterEnter, - onEnterCancelled, - onBeforeLeave, - onLeave, - onAfterLeave, - onLeaveCancelled, - onBeforeAppear, - onAppear, - onAfterAppear, - onAppearCancelled - }, - state, - instance -) { - const key = String(vnode.key); - const leavingVNodesCache = getLeavingNodesForType(state, vnode); - const callHook = (hook, args) => { - hook && - callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args); - }; - const hooks = { - persisted, - beforeEnter(el) { - let hook = onBeforeEnter; - if (!state.isMounted) { - if (appear) { - hook = onBeforeAppear || onBeforeEnter; - } else { - return - } - } - // for same element (v-show) - if (el._leaveCb) { - el._leaveCb(true /* cancelled */); - } - // for toggled element with same key (v-if) - const leavingVNode = leavingVNodesCache[key]; - if ( - leavingVNode && - isSameVNodeType(vnode, leavingVNode) && - leavingVNode.el._leaveCb - ) { - // force early removal (not cancelled) - leavingVNode.el._leaveCb(); - } - callHook(hook, [el]); - }, - enter(el) { - let hook = onEnter; - let afterHook = onAfterEnter; - let cancelHook = onEnterCancelled; - if (!state.isMounted) { - if (appear) { - hook = onAppear || onEnter; - afterHook = onAfterAppear || onAfterEnter; - cancelHook = onAppearCancelled || onEnterCancelled; - } else { - return - } - } - let called = false; - const done = (el._enterCb = cancelled => { - if (called) return - called = true; - if (cancelled) { - callHook(cancelHook, [el]); - } else { - callHook(afterHook, [el]); - } - if (hooks.delayedLeave) { - hooks.delayedLeave(); - } - el._enterCb = undefined; - }); - if (hook) { - hook(el, done); - if (hook.length <= 1) { - done(); - } - } else { - done(); - } - }, - leave(el, remove) { - const key = String(vnode.key); - if (el._enterCb) { - el._enterCb(true /* cancelled */); - } - if (state.isUnmounting) { - return remove() - } - callHook(onBeforeLeave, [el]); - let called = false; - const done = (el._leaveCb = cancelled => { - if (called) return - called = true; - remove(); - if (cancelled) { - callHook(onLeaveCancelled, [el]); - } else { - callHook(onAfterLeave, [el]); - } - el._leaveCb = undefined; - if (leavingVNodesCache[key] === vnode) { - delete leavingVNodesCache[key]; - } - }); - leavingVNodesCache[key] = vnode; - if (onLeave) { - onLeave(el, done); - if (onLeave.length <= 1) { - done(); - } - } else { - done(); - } - } - }; - return hooks -} -// the placeholder really only handles one special case: KeepAlive -// in the case of a KeepAlive in a leave phase we need to return a KeepAlive -// placeholder with empty content to avoid the KeepAlive instance from being -// unmounted. -function emptyPlaceholder(vnode) { - if (isKeepAlive(vnode)) { - vnode = cloneVNode(vnode); - vnode.children = null; - return vnode - } -} -function getKeepAliveChild(vnode) { - return isKeepAlive(vnode) - ? vnode.children - ? vnode.children[0] - : undefined - : vnode -} -function setTransitionHooks(vnode, hooks) { - if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) { - setTransitionHooks(vnode.component.subTree, hooks); - } else { - vnode.transition = hooks; - } -} -function getTransitionRawChildren(children, keepComment = false) { - let ret = []; - let keyedFragmentCount = 0; - for (let i = 0; i < children.length; i++) { - const child = children[i]; - // handle fragment children case, e.g. v-for - if (child.type === Fragment) { - if (child.patchFlag & 128 /* KEYED_FRAGMENT */) keyedFragmentCount++; - ret = ret.concat(getTransitionRawChildren(child.children, keepComment)); - } - // comment placeholders should be skipped, e.g. v-if - else if (keepComment || child.type !== Comment) { - ret.push(child); - } - } - // #1126 if a transition children list contains multiple sub fragments, these - // fragments will be merged into a flat children array. Since each v-for - // fragment may contain different static bindings inside, we need to de-top - // these children to force full diffs to ensure correct behavior. - if (keyedFragmentCount > 1) { - for (let i = 0; i < ret.length; i++) { - ret[i].patchFlag = -2; /* BAIL */ - } - } - return ret +function useTransitionState() { + const state = { + isMounted: false, + isLeaving: false, + isUnmounting: false, + leavingVNodes: new Map() + }; + onMounted(() => { + state.isMounted = true; + }); + onBeforeUnmount(() => { + state.isUnmounting = true; + }); + return state; +} +const TransitionHookValidator = [Function, Array]; +const BaseTransitionImpl = { + name: `BaseTransition`, + props: { + mode: String, + appear: Boolean, + persisted: Boolean, + // enter + onBeforeEnter: TransitionHookValidator, + onEnter: TransitionHookValidator, + onAfterEnter: TransitionHookValidator, + onEnterCancelled: TransitionHookValidator, + // leave + onBeforeLeave: TransitionHookValidator, + onLeave: TransitionHookValidator, + onAfterLeave: TransitionHookValidator, + onLeaveCancelled: TransitionHookValidator, + // appear + onBeforeAppear: TransitionHookValidator, + onAppear: TransitionHookValidator, + onAfterAppear: TransitionHookValidator, + onAppearCancelled: TransitionHookValidator + }, + setup(props, { slots }) { + const instance = getCurrentInstance(); + const state = useTransitionState(); + let prevTransitionKey; + return () => { + const children = slots.default && getTransitionRawChildren(slots.default(), true); + if (!children || !children.length) { + return; + } + // warn multiple elements + if ((process.env.NODE_ENV !== 'production') && children.length > 1) { + warn(' can only be used on a single element or component. Use ' + + ' for lists.'); + } + // there's no need to track reactivity for these props so use the raw + // props for a bit better perf + const rawProps = toRaw(props); + const { mode } = rawProps; + // check mode + if ((process.env.NODE_ENV !== 'production') && mode && !['in-out', 'out-in', 'default'].includes(mode)) { + warn(`invalid mode: ${mode}`); + } + // at this point children has a guaranteed length of 1. + const child = children[0]; + if (state.isLeaving) { + return emptyPlaceholder(child); + } + // in the case of , we need to + // compare the type of the kept-alive children. + const innerChild = getKeepAliveChild(child); + if (!innerChild) { + return emptyPlaceholder(child); + } + const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance); + setTransitionHooks(innerChild, enterHooks); + const oldChild = instance.subTree; + const oldInnerChild = oldChild && getKeepAliveChild(oldChild); + let transitionKeyChanged = false; + const { getTransitionKey } = innerChild.type; + if (getTransitionKey) { + const key = getTransitionKey(); + if (prevTransitionKey === undefined) { + prevTransitionKey = key; + } + else if (key !== prevTransitionKey) { + prevTransitionKey = key; + transitionKeyChanged = true; + } + } + // handle mode + if (oldInnerChild && + oldInnerChild.type !== Comment && + (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) { + const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance); + // update old tree's hooks in case of dynamic transition + setTransitionHooks(oldInnerChild, leavingHooks); + // switching between different views + if (mode === 'out-in') { + state.isLeaving = true; + // return placeholder node and queue update when leave finishes + leavingHooks.afterLeave = () => { + state.isLeaving = false; + instance.update(); + }; + return emptyPlaceholder(child); + } + else if (mode === 'in-out') { + leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => { + const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild); + leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild; + // early removal callback + el._leaveCb = () => { + earlyRemove(); + el._leaveCb = undefined; + delete enterHooks.delayedLeave; + }; + enterHooks.delayedLeave = delayedLeave; + }; + } + } + return child; + }; + } +}; +// export the public type for h/tsx inference +// also to avoid inline import() in generated d.ts files +const BaseTransition = BaseTransitionImpl; +function getLeavingNodesForType(state, vnode) { + const { leavingVNodes } = state; + let leavingVNodesCache = leavingVNodes.get(vnode.type); + if (!leavingVNodesCache) { + leavingVNodesCache = Object.create(null); + leavingVNodes.set(vnode.type, leavingVNodesCache); + } + return leavingVNodesCache; +} +// The transition hooks are attached to the vnode as vnode.transition +// and will be called at appropriate timing in the renderer. +function resolveTransitionHooks(vnode, props, state, instance) { + const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props; + const key = String(vnode.key); + const leavingVNodesCache = getLeavingNodesForType(state, vnode); + const callHook = (hook, args) => { + hook && + callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args); + }; + const hooks = { + mode, + persisted, + beforeEnter(el) { + let hook = onBeforeEnter; + if (!state.isMounted) { + if (appear) { + hook = onBeforeAppear || onBeforeEnter; + } + else { + return; + } + } + // for same element (v-show) + if (el._leaveCb) { + el._leaveCb(true /* cancelled */); + } + // for toggled element with same key (v-if) + const leavingVNode = leavingVNodesCache[key]; + if (leavingVNode && + isSameVNodeType(vnode, leavingVNode) && + leavingVNode.el._leaveCb) { + // force early removal (not cancelled) + leavingVNode.el._leaveCb(); + } + callHook(hook, [el]); + }, + enter(el) { + let hook = onEnter; + let afterHook = onAfterEnter; + let cancelHook = onEnterCancelled; + if (!state.isMounted) { + if (appear) { + hook = onAppear || onEnter; + afterHook = onAfterAppear || onAfterEnter; + cancelHook = onAppearCancelled || onEnterCancelled; + } + else { + return; + } + } + let called = false; + const done = (el._enterCb = (cancelled) => { + if (called) + return; + called = true; + if (cancelled) { + callHook(cancelHook, [el]); + } + else { + callHook(afterHook, [el]); + } + if (hooks.delayedLeave) { + hooks.delayedLeave(); + } + el._enterCb = undefined; + }); + if (hook) { + hook(el, done); + if (hook.length <= 1) { + done(); + } + } + else { + done(); + } + }, + leave(el, remove) { + const key = String(vnode.key); + if (el._enterCb) { + el._enterCb(true /* cancelled */); + } + if (state.isUnmounting) { + return remove(); + } + callHook(onBeforeLeave, [el]); + let called = false; + const done = (el._leaveCb = (cancelled) => { + if (called) + return; + called = true; + remove(); + if (cancelled) { + callHook(onLeaveCancelled, [el]); + } + else { + callHook(onAfterLeave, [el]); + } + el._leaveCb = undefined; + if (leavingVNodesCache[key] === vnode) { + delete leavingVNodesCache[key]; + } + }); + leavingVNodesCache[key] = vnode; + if (onLeave) { + onLeave(el, done); + if (onLeave.length <= 1) { + done(); + } + } + else { + done(); + } + }, + clone(vnode) { + return resolveTransitionHooks(vnode, props, state, instance); + } + }; + return hooks; +} +// the placeholder really only handles one special case: KeepAlive +// in the case of a KeepAlive in a leave phase we need to return a KeepAlive +// placeholder with empty content to avoid the KeepAlive instance from being +// unmounted. +function emptyPlaceholder(vnode) { + if (isKeepAlive(vnode)) { + vnode = cloneVNode(vnode); + vnode.children = null; + return vnode; + } +} +function getKeepAliveChild(vnode) { + return isKeepAlive(vnode) + ? vnode.children + ? vnode.children[0] + : undefined + : vnode; +} +function setTransitionHooks(vnode, hooks) { + if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) { + setTransitionHooks(vnode.component.subTree, hooks); + } + else if ( vnode.shapeFlag & 128 /* SUSPENSE */) { + vnode.ssContent.transition = hooks.clone(vnode.ssContent); + vnode.ssFallback.transition = hooks.clone(vnode.ssFallback); + } + else { + vnode.transition = hooks; + } +} +function getTransitionRawChildren(children, keepComment = false) { + let ret = []; + let keyedFragmentCount = 0; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + // handle fragment children case, e.g. v-for + if (child.type === Fragment) { + if (child.patchFlag & 128 /* KEYED_FRAGMENT */) + keyedFragmentCount++; + ret = ret.concat(getTransitionRawChildren(child.children, keepComment)); + } + // comment placeholders should be skipped, e.g. v-if + else if (keepComment || child.type !== Comment) { + ret.push(child); + } + } + // #1126 if a transition children list contains multiple sub fragments, these + // fragments will be merged into a flat children array. Since each v-for + // fragment may contain different static bindings inside, we need to de-top + // these children to force full diffs to ensure correct behavior. + if (keyedFragmentCount > 1) { + for (let i = 0; i < ret.length; i++) { + ret[i].patchFlag = -2 /* BAIL */; + } + } + return ret; } -const isKeepAlive = vnode => vnode.type.__isKeepAlive; -const KeepAliveImpl = { - name: `KeepAlive`, - // Marker for special handling inside the renderer. We are not using a === - // check directly on KeepAlive in the renderer, because importing it directly - // would prevent it from being tree-shaken. - __isKeepAlive: true, - inheritRef: true, - props: { - include: [String, RegExp, Array], - exclude: [String, RegExp, Array], - max: [String, Number] - }, - setup(props, { slots }) { - const cache = new Map(); - const keys = new Set(); - let current = null; - const instance = getCurrentInstance(); - const parentSuspense = instance.suspense; - // KeepAlive communicates with the instantiated renderer via the - // ctx where the renderer passes in its internals, - // and the KeepAlive instance exposes activate/deactivate implementations. - // The whole point of this is to avoid importing KeepAlive directly in the - // renderer to facilitate tree-shaking. - const sharedContext = instance.ctx; - const { - renderer: { - p: patch, - m: move, - um: _unmount, - o: { createElement } - } - } = sharedContext; - const storageContainer = createElement('div'); - sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => { - const instance = vnode.component; - move(vnode, container, anchor, 0 /* ENTER */, parentSuspense); - // in case props have changed - patch( - instance.vnode, - vnode, - container, - anchor, - instance, - parentSuspense, - isSVG, - optimized - ); - queuePostRenderEffect(() => { - instance.isDeactivated = false; - if (instance.a) { - invokeArrayFns(instance.a); - } - const vnodeHook = vnode.props && vnode.props.onVnodeMounted; - if (vnodeHook) { - invokeVNodeHook(vnodeHook, instance.parent, vnode); - } - }, parentSuspense); - }; - sharedContext.deactivate = vnode => { - const instance = vnode.component; - move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense); - queuePostRenderEffect(() => { - if (instance.da) { - invokeArrayFns(instance.da); - } - const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted; - if (vnodeHook) { - invokeVNodeHook(vnodeHook, instance.parent, vnode); - } - instance.isDeactivated = true; - }, parentSuspense); - }; - function unmount(vnode) { - // reset the shapeFlag so it can be properly unmounted - resetShapeFlag(vnode); - _unmount(vnode, instance, parentSuspense); - } - function pruneCache(filter) { - cache.forEach((vnode, key) => { - const name = getName(vnode.type); - if (name && (!filter || !filter(name))) { - pruneCacheEntry(key); - } - }); - } - function pruneCacheEntry(key) { - const cached = cache.get(key); - if (!current || cached.type !== current.type) { - unmount(cached); - } else if (current) { - // current active instance should no longer be kept-alive. - // we can't unmount it now but it might be later, so reset its flag now. - resetShapeFlag(current); - } - cache.delete(key); - keys.delete(key); - } - watch( - () => [props.include, props.exclude], - ([include, exclude]) => { - include && pruneCache(name => matches(include, name)); - exclude && pruneCache(name => matches(exclude, name)); - } - ); - // cache sub tree in beforeMount/Update (i.e. right after the render) - let pendingCacheKey = null; - const cacheSubtree = () => { - // fix #1621, the pendingCacheKey could be 0 - if (pendingCacheKey != null) { - cache.set(pendingCacheKey, instance.subTree); - } - }; - onBeforeMount(cacheSubtree); - onBeforeUpdate(cacheSubtree); - onBeforeUnmount(() => { - cache.forEach(cached => { - const { subTree, suspense } = instance; - if (cached.type === subTree.type) { - // current instance will be unmounted as part of keep-alive's unmount - resetShapeFlag(subTree); - // but invoke its deactivated hook here - const da = subTree.component.da; - da && queuePostRenderEffect(da, suspense); - return - } - unmount(cached); - }); - }); - return () => { - pendingCacheKey = null; - if (!slots.default) { - return null - } - const children = slots.default(); - let vnode = children[0]; - if (children.length > 1) { - if (process.env.NODE_ENV !== 'production') { - warn(`KeepAlive should contain exactly one component child.`); - } - current = null; - return children - } else if ( - !isVNode(vnode) || - !(vnode.shapeFlag & 4) /* STATEFUL_COMPONENT */ - ) { - current = null; - return vnode - } - const comp = vnode.type; - const name = getName(comp); - const { include, exclude, max } = props; - if ( - (include && (!name || !matches(include, name))) || - (exclude && name && matches(exclude, name)) - ) { - return (current = vnode) - } - const key = vnode.key == null ? comp : vnode.key; - const cachedVNode = cache.get(key); - // clone vnode if it's reused because we are going to mutate it - if (vnode.el) { - vnode = cloneVNode(vnode); - } - // #1513 it's possible for the returned vnode to be cloned due to attr - // fallthrough or scopeId, so the vnode here may not be the final vnode - // that is mounted. Instead of caching it directly, we store the pending - // key and cache `instance.subTree` (the normalized vnode) in - // beforeMount/beforeUpdate hooks. - pendingCacheKey = key; - if (cachedVNode) { - // copy over mounted state - vnode.el = cachedVNode.el; - vnode.component = cachedVNode.component; - if (vnode.transition) { - // recursively update transition hooks on subTree - setTransitionHooks(vnode, vnode.transition); - } - // avoid vnode being mounted as fresh - vnode.shapeFlag |= 512; /* COMPONENT_KEPT_ALIVE */ - // make this key the freshest - keys.delete(key); - keys.add(key); - } else { - keys.add(key); - // prune oldest entry - if (max && keys.size > parseInt(max, 10)) { - pruneCacheEntry(keys.values().next().value); - } - } - // avoid vnode being unmounted - vnode.shapeFlag |= 256; /* COMPONENT_SHOULD_KEEP_ALIVE */ - current = vnode; - return vnode - } - } -}; -// export the public type for h/tsx inference -// also to avoid inline import() in generated d.ts files -const KeepAlive = KeepAliveImpl; -function getName(comp) { - return comp.displayName || comp.name -} -function matches(pattern, name) { - if (isArray(pattern)) { - return pattern.some(p => matches(p, name)) - } else if (isString(pattern)) { - return pattern.split(',').indexOf(name) > -1 - } else if (pattern.test) { - return pattern.test(name) - } - /* istanbul ignore next */ - return false -} -function onActivated(hook, target) { - registerKeepAliveHook(hook, 'a' /* ACTIVATED */, target); -} -function onDeactivated(hook, target) { - registerKeepAliveHook(hook, 'da' /* DEACTIVATED */, target); -} -function registerKeepAliveHook(hook, type, target = currentInstance) { - // cache the deactivate branch check wrapper for injected hooks so the same - // hook can be properly deduped by the scheduler. "__wdc" stands for "with - // deactivation check". - const wrappedHook = - hook.__wdc || - (hook.__wdc = () => { - // only fire the hook if the target instance is NOT in a deactivated branch. - let current = target; - while (current) { - if (current.isDeactivated) { - return - } - current = current.parent; - } - hook(); - }); - injectHook(type, wrappedHook, target); - // In addition to registering it on the target instance, we walk up the parent - // chain and register it on all ancestor instances that are keep-alive roots. - // This avoids the need to walk the entire component tree when invoking these - // hooks, and more importantly, avoids the need to track child components in - // arrays. - if (target) { - let current = target.parent; - while (current && current.parent) { - if (isKeepAlive(current.parent.vnode)) { - injectToKeepAliveRoot(wrappedHook, type, target, current); - } - current = current.parent; - } - } -} -function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) { - // injectHook wraps the original for error handling, so make sure to remove - // the wrapped version. - const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */); - onUnmounted(() => { - remove(keepAliveRoot[type], injected); - }, target); -} -function resetShapeFlag(vnode) { - let shapeFlag = vnode.shapeFlag; - if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) { - shapeFlag -= 256; /* COMPONENT_SHOULD_KEEP_ALIVE */ - } - if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) { - shapeFlag -= 512; /* COMPONENT_KEPT_ALIVE */ - } - vnode.shapeFlag = shapeFlag; +const isKeepAlive = (vnode) => vnode.type.__isKeepAlive; +const KeepAliveImpl = { + name: `KeepAlive`, + // Marker for special handling inside the renderer. We are not using a === + // check directly on KeepAlive in the renderer, because importing it directly + // would prevent it from being tree-shaken. + __isKeepAlive: true, + inheritRef: true, + props: { + include: [String, RegExp, Array], + exclude: [String, RegExp, Array], + max: [String, Number] + }, + setup(props, { slots }) { + const cache = new Map(); + const keys = new Set(); + let current = null; + const instance = getCurrentInstance(); + const parentSuspense = instance.suspense; + // KeepAlive communicates with the instantiated renderer via the + // ctx where the renderer passes in its internals, + // and the KeepAlive instance exposes activate/deactivate implementations. + // The whole point of this is to avoid importing KeepAlive directly in the + // renderer to facilitate tree-shaking. + const sharedContext = instance.ctx; + const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext; + const storageContainer = createElement('div'); + sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => { + const instance = vnode.component; + move(vnode, container, anchor, 0 /* ENTER */, parentSuspense); + // in case props have changed + patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, optimized); + queuePostRenderEffect(() => { + instance.isDeactivated = false; + if (instance.a) { + invokeArrayFns(instance.a); + } + const vnodeHook = vnode.props && vnode.props.onVnodeMounted; + if (vnodeHook) { + invokeVNodeHook(vnodeHook, instance.parent, vnode); + } + }, parentSuspense); + }; + sharedContext.deactivate = (vnode) => { + const instance = vnode.component; + move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense); + queuePostRenderEffect(() => { + if (instance.da) { + invokeArrayFns(instance.da); + } + const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted; + if (vnodeHook) { + invokeVNodeHook(vnodeHook, instance.parent, vnode); + } + instance.isDeactivated = true; + }, parentSuspense); + }; + function unmount(vnode) { + // reset the shapeFlag so it can be properly unmounted + resetShapeFlag(vnode); + _unmount(vnode, instance, parentSuspense); + } + function pruneCache(filter) { + cache.forEach((vnode, key) => { + const name = getName(vnode.type); + if (name && (!filter || !filter(name))) { + pruneCacheEntry(key); + } + }); + } + function pruneCacheEntry(key) { + const cached = cache.get(key); + if (!current || cached.type !== current.type) { + unmount(cached); + } + else if (current) { + // current active instance should no longer be kept-alive. + // we can't unmount it now but it might be later, so reset its flag now. + resetShapeFlag(current); + } + cache.delete(key); + keys.delete(key); + } + // prune cache on include/exclude prop change + watch(() => [props.include, props.exclude], ([include, exclude]) => { + include && pruneCache(name => matches(include, name)); + exclude && pruneCache(name => !matches(exclude, name)); + }, + // prune post-render after `current` has been updated + { flush: 'post' }); + // cache sub tree after render + let pendingCacheKey = null; + const cacheSubtree = () => { + // fix #1621, the pendingCacheKey could be 0 + if (pendingCacheKey != null) { + cache.set(pendingCacheKey, getInnerChild(instance.subTree)); + } + }; + onMounted(cacheSubtree); + onUpdated(cacheSubtree); + onBeforeUnmount(() => { + cache.forEach(cached => { + const { subTree, suspense } = instance; + const vnode = getInnerChild(subTree); + if (cached.type === vnode.type) { + // current instance will be unmounted as part of keep-alive's unmount + resetShapeFlag(vnode); + // but invoke its deactivated hook here + const da = vnode.component.da; + da && queuePostRenderEffect(da, suspense); + return; + } + unmount(cached); + }); + }); + return () => { + pendingCacheKey = null; + if (!slots.default) { + return null; + } + const children = slots.default(); + const rawVNode = children[0]; + if (children.length > 1) { + if ((process.env.NODE_ENV !== 'production')) { + warn(`KeepAlive should contain exactly one component child.`); + } + current = null; + return children; + } + else if (!isVNode(rawVNode) || + (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) && + !(rawVNode.shapeFlag & 128 /* SUSPENSE */))) { + current = null; + return rawVNode; + } + let vnode = getInnerChild(rawVNode); + const comp = vnode.type; + const name = getName(comp); + const { include, exclude, max } = props; + if ((include && (!name || !matches(include, name))) || + (exclude && name && matches(exclude, name))) { + current = vnode; + return rawVNode; + } + const key = vnode.key == null ? comp : vnode.key; + const cachedVNode = cache.get(key); + // clone vnode if it's reused because we are going to mutate it + if (vnode.el) { + vnode = cloneVNode(vnode); + if (rawVNode.shapeFlag & 128 /* SUSPENSE */) { + rawVNode.ssContent = vnode; + } + } + // #1513 it's possible for the returned vnode to be cloned due to attr + // fallthrough or scopeId, so the vnode here may not be the final vnode + // that is mounted. Instead of caching it directly, we store the pending + // key and cache `instance.subTree` (the normalized vnode) in + // beforeMount/beforeUpdate hooks. + pendingCacheKey = key; + if (cachedVNode) { + // copy over mounted state + vnode.el = cachedVNode.el; + vnode.component = cachedVNode.component; + if (vnode.transition) { + // recursively update transition hooks on subTree + setTransitionHooks(vnode, vnode.transition); + } + // avoid vnode being mounted as fresh + vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */; + // make this key the freshest + keys.delete(key); + keys.add(key); + } + else { + keys.add(key); + // prune oldest entry + if (max && keys.size > parseInt(max, 10)) { + pruneCacheEntry(keys.values().next().value); + } + } + // avoid vnode being unmounted + vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */; + current = vnode; + return rawVNode; + }; + } +}; +// export the public type for h/tsx inference +// also to avoid inline import() in generated d.ts files +const KeepAlive = KeepAliveImpl; +function getName(comp) { + return comp.displayName || comp.name; +} +function matches(pattern, name) { + if (isArray(pattern)) { + return pattern.some((p) => matches(p, name)); + } + else if (isString(pattern)) { + return pattern.split(',').indexOf(name) > -1; + } + else if (pattern.test) { + return pattern.test(name); + } + /* istanbul ignore next */ + return false; +} +function onActivated(hook, target) { + registerKeepAliveHook(hook, "a" /* ACTIVATED */, target); +} +function onDeactivated(hook, target) { + registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target); +} +function registerKeepAliveHook(hook, type, target = currentInstance) { + // cache the deactivate branch check wrapper for injected hooks so the same + // hook can be properly deduped by the scheduler. "__wdc" stands for "with + // deactivation check". + const wrappedHook = hook.__wdc || + (hook.__wdc = () => { + // only fire the hook if the target instance is NOT in a deactivated branch. + let current = target; + while (current) { + if (current.isDeactivated) { + return; + } + current = current.parent; + } + hook(); + }); + injectHook(type, wrappedHook, target); + // In addition to registering it on the target instance, we walk up the parent + // chain and register it on all ancestor instances that are keep-alive roots. + // This avoids the need to walk the entire component tree when invoking these + // hooks, and more importantly, avoids the need to track child components in + // arrays. + if (target) { + let current = target.parent; + while (current && current.parent) { + if (isKeepAlive(current.parent.vnode)) { + injectToKeepAliveRoot(wrappedHook, type, target, current); + } + current = current.parent; + } + } +} +function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) { + // injectHook wraps the original for error handling, so make sure to remove + // the wrapped version. + const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */); + onUnmounted(() => { + remove(keepAliveRoot[type], injected); + }, target); +} +function resetShapeFlag(vnode) { + let shapeFlag = vnode.shapeFlag; + if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) { + shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */; + } + if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) { + shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */; + } + vnode.shapeFlag = shapeFlag; +} +function getInnerChild(vnode) { + return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode; } -const isInternalKey = key => key[0] === '_' || key === '$stable'; -const normalizeSlotValue = value => - isArray(value) ? value.map(normalizeVNode) : [normalizeVNode(value)]; -const normalizeSlot = (key, rawSlot, ctx) => - withCtx(props => { - if (process.env.NODE_ENV !== 'production' && currentInstance) { - warn( - `Slot "${key}" invoked outside of the render function: ` + - `this will not track dependencies used in the slot. ` + - `Invoke the slot function inside the render function instead.` - ); - } - return normalizeSlotValue(rawSlot(props)) - }, ctx); -const normalizeObjectSlots = (rawSlots, slots) => { - const ctx = rawSlots._ctx; - for (const key in rawSlots) { - if (isInternalKey(key)) continue - const value = rawSlots[key]; - if (isFunction(value)) { - slots[key] = normalizeSlot(key, value, ctx); - } else if (value != null) { - if (process.env.NODE_ENV !== 'production') { - warn( - `Non-function value encountered for slot "${key}". ` + - `Prefer function slots for better performance.` - ); - } - const normalized = normalizeSlotValue(value); - slots[key] = () => normalized; - } - } -}; -const normalizeVNodeSlots = (instance, children) => { - if (process.env.NODE_ENV !== 'production' && !isKeepAlive(instance.vnode)) { - warn( - `Non-function value encountered for default slot. ` + - `Prefer function slots for better performance.` - ); - } - const normalized = normalizeSlotValue(children); - instance.slots.default = () => normalized; -}; -const initSlots = (instance, children) => { - if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) { - const type = children._; - if (type) { - instance.slots = children; - // make compiler marker non-enumerable - def(children, '_', type); - } else { - normalizeObjectSlots(children, (instance.slots = {})); - } - } else { - instance.slots = {}; - if (children) { - normalizeVNodeSlots(instance, children); - } - } - def(instance.slots, InternalObjectKey, 1); -}; -const updateSlots = (instance, children) => { - const { vnode, slots } = instance; - let needDeletionCheck = true; - let deletionComparisonTarget = EMPTY_OBJ; - if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) { - const type = children._; - if (type) { - // compiled slots. - if (process.env.NODE_ENV !== 'production' && isHmrUpdating) { - // Parent was HMR updated so slot content may have changed. - // force update slots and mark instance for hmr as well - extend(slots, children); - } else if (type === 1 /* STABLE */) { - // compiled AND stable. - // no need to update, and skip stale slots removal. - needDeletionCheck = false; - } else { - // compiled but dynamic (v-if/v-for on slots) - update slots, but skip - // normalization. - extend(slots, children); - } - } else { - needDeletionCheck = !children.$stable; - normalizeObjectSlots(children, slots); - } - deletionComparisonTarget = children; - } else if (children) { - // non slot object children (direct value) passed to a component - normalizeVNodeSlots(instance, children); - deletionComparisonTarget = { default: 1 }; - } - // delete stale slots - if (needDeletionCheck) { - for (const key in slots) { - if (!isInternalKey(key) && !(key in deletionComparisonTarget)) { - delete slots[key]; - } - } - } +const isInternalKey = (key) => key[0] === '_' || key === '$stable'; +const normalizeSlotValue = (value) => isArray(value) + ? value.map(normalizeVNode) + : [normalizeVNode(value)]; +const normalizeSlot = (key, rawSlot, ctx) => withCtx((props) => { + if ((process.env.NODE_ENV !== 'production') && currentInstance) { + warn(`Slot "${key}" invoked outside of the render function: ` + + `this will not track dependencies used in the slot. ` + + `Invoke the slot function inside the render function instead.`); + } + return normalizeSlotValue(rawSlot(props)); +}, ctx); +const normalizeObjectSlots = (rawSlots, slots) => { + const ctx = rawSlots._ctx; + for (const key in rawSlots) { + if (isInternalKey(key)) + continue; + const value = rawSlots[key]; + if (isFunction(value)) { + slots[key] = normalizeSlot(key, value, ctx); + } + else if (value != null) { + if ((process.env.NODE_ENV !== 'production')) { + warn(`Non-function value encountered for slot "${key}". ` + + `Prefer function slots for better performance.`); + } + const normalized = normalizeSlotValue(value); + slots[key] = () => normalized; + } + } +}; +const normalizeVNodeSlots = (instance, children) => { + if ((process.env.NODE_ENV !== 'production') && !isKeepAlive(instance.vnode)) { + warn(`Non-function value encountered for default slot. ` + + `Prefer function slots for better performance.`); + } + const normalized = normalizeSlotValue(children); + instance.slots.default = () => normalized; +}; +const initSlots = (instance, children) => { + if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) { + const type = children._; + if (type) { + instance.slots = children; + // make compiler marker non-enumerable + def(children, '_', type); + } + else { + normalizeObjectSlots(children, (instance.slots = {})); + } + } + else { + instance.slots = {}; + if (children) { + normalizeVNodeSlots(instance, children); + } + } + def(instance.slots, InternalObjectKey, 1); +}; +const updateSlots = (instance, children) => { + const { vnode, slots } = instance; + let needDeletionCheck = true; + let deletionComparisonTarget = EMPTY_OBJ; + if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) { + const type = children._; + if (type) { + // compiled slots. + if ((process.env.NODE_ENV !== 'production') && isHmrUpdating) { + // Parent was HMR updated so slot content may have changed. + // force update slots and mark instance for hmr as well + extend(slots, children); + } + else if (type === 1 /* STABLE */) { + // compiled AND stable. + // no need to update, and skip stale slots removal. + needDeletionCheck = false; + } + else { + // compiled but dynamic (v-if/v-for on slots) - update slots, but skip + // normalization. + extend(slots, children); + } + } + else { + needDeletionCheck = !children.$stable; + normalizeObjectSlots(children, slots); + } + deletionComparisonTarget = children; + } + else if (children) { + // non slot object children (direct value) passed to a component + normalizeVNodeSlots(instance, children); + deletionComparisonTarget = { default: 1 }; + } + // delete stale slots + if (needDeletionCheck) { + for (const key in slots) { + if (!isInternalKey(key) && !(key in deletionComparisonTarget)) { + delete slots[key]; + } + } + } }; /** @@ -4378,5358 +4093,4636 @@ return withDirectives(h(comp), [ [foo, this.x], [bar, this.y] ]) -*/ -const isBuiltInDirective = /*#__PURE__*/ makeMap( - 'bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text' -); -function validateDirectiveName(name) { - if (isBuiltInDirective(name)) { - warn('Do not use built-in directive ids as custom directive id: ' + name); - } -} -/** - * Adds directives to a VNode. - */ -function withDirectives(vnode, directives) { - const internalInstance = currentRenderingInstance; - if (internalInstance === null) { - process.env.NODE_ENV !== 'production' && - warn(`withDirectives can only be used inside render functions.`); - return vnode - } - const instance = internalInstance.proxy; - const bindings = vnode.dirs || (vnode.dirs = []); - for (let i = 0; i < directives.length; i++) { - let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i]; - if (isFunction(dir)) { - dir = { - mounted: dir, - updated: dir - }; - } - bindings.push({ - dir, - instance, - value, - oldValue: void 0, - arg, - modifiers - }); - } - return vnode -} -function invokeDirectiveHook(vnode, prevVNode, instance, name) { - const bindings = vnode.dirs; - const oldBindings = prevVNode && prevVNode.dirs; - for (let i = 0; i < bindings.length; i++) { - const binding = bindings[i]; - if (oldBindings) { - binding.oldValue = oldBindings[i].value; - } - const hook = binding.dir[name]; - if (hook) { - callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [ - vnode.el, - binding, - vnode, - prevVNode - ]); - } - } +*/ +const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text'); +function validateDirectiveName(name) { + if (isBuiltInDirective(name)) { + warn('Do not use built-in directive ids as custom directive id: ' + name); + } +} +/** + * Adds directives to a VNode. + */ +function withDirectives(vnode, directives) { + const internalInstance = currentRenderingInstance; + if (internalInstance === null) { + (process.env.NODE_ENV !== 'production') && warn(`withDirectives can only be used inside render functions.`); + return vnode; + } + const instance = internalInstance.proxy; + const bindings = vnode.dirs || (vnode.dirs = []); + for (let i = 0; i < directives.length; i++) { + let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i]; + if (isFunction(dir)) { + dir = { + mounted: dir, + updated: dir + }; + } + bindings.push({ + dir, + instance, + value, + oldValue: void 0, + arg, + modifiers + }); + } + return vnode; +} +function invokeDirectiveHook(vnode, prevVNode, instance, name) { + const bindings = vnode.dirs; + const oldBindings = prevVNode && prevVNode.dirs; + for (let i = 0; i < bindings.length; i++) { + const binding = bindings[i]; + if (oldBindings) { + binding.oldValue = oldBindings[i].value; + } + const hook = binding.dir[name]; + if (hook) { + callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [ + vnode.el, + binding, + vnode, + prevVNode + ]); + } + } } -function createAppContext() { - return { - app: null, - config: { - isNativeTag: NO, - performance: false, - globalProperties: {}, - optionMergeStrategies: {}, - isCustomElement: NO, - errorHandler: undefined, - warnHandler: undefined - }, - mixins: [], - components: {}, - directives: {}, - provides: Object.create(null) - } -} -let uid$1 = 0; -function createAppAPI(render, hydrate) { - return function createApp(rootComponent, rootProps = null) { - if (rootProps != null && !isObject(rootProps)) { - process.env.NODE_ENV !== 'production' && - warn(`root props passed to app.mount() must be an object.`); - rootProps = null; - } - const context = createAppContext(); - const installedPlugins = new Set(); - let isMounted = false; - const app = (context.app = { - _uid: uid$1++, - _component: rootComponent, - _props: rootProps, - _container: null, - _context: context, - version, - get config() { - return context.config - }, - set config(v) { - if (process.env.NODE_ENV !== 'production') { - warn( - `app.config cannot be replaced. Modify individual options instead.` - ); - } - }, - use(plugin, ...options) { - if (installedPlugins.has(plugin)) { - process.env.NODE_ENV !== 'production' && - warn(`Plugin has already been applied to target app.`); - } else if (plugin && isFunction(plugin.install)) { - installedPlugins.add(plugin); - plugin.install(app, ...options); - } else if (isFunction(plugin)) { - installedPlugins.add(plugin); - plugin(app, ...options); - } else if (process.env.NODE_ENV !== 'production') { - warn( - `A plugin must either be a function or an object with an "install" ` + - `function.` - ); - } - return app - }, - mixin(mixin) { - if (__VUE_OPTIONS_API__) { - if (!context.mixins.includes(mixin)) { - context.mixins.push(mixin); - } else if (process.env.NODE_ENV !== 'production') { - warn( - 'Mixin has already been applied to target app' + - (mixin.name ? `: ${mixin.name}` : '') - ); - } - } else if (process.env.NODE_ENV !== 'production') { - warn('Mixins are only available in builds supporting Options API'); - } - return app - }, - component(name, component) { - if (process.env.NODE_ENV !== 'production') { - validateComponentName(name, context.config); - } - if (!component) { - return context.components[name] - } - if (process.env.NODE_ENV !== 'production' && context.components[name]) { - warn(`Component "${name}" has already been registered in target app.`); - } - context.components[name] = component; - return app - }, - directive(name, directive) { - if (process.env.NODE_ENV !== 'production') { - validateDirectiveName(name); - } - if (!directive) { - return context.directives[name] - } - if (process.env.NODE_ENV !== 'production' && context.directives[name]) { - warn(`Directive "${name}" has already been registered in target app.`); - } - context.directives[name] = directive; - return app - }, - mount(rootContainer, isHydrate) { - if (!isMounted) { - const vnode = createVNode(rootComponent, rootProps); - // store app context on the root VNode. - // this will be set on the root instance on initial mount. - vnode.appContext = context; - // HMR root reload - if (process.env.NODE_ENV !== 'production') { - context.reload = () => { - render(cloneVNode(vnode), rootContainer); - }; - } - if (isHydrate && hydrate) { - hydrate(vnode, rootContainer); - } else { - render(vnode, rootContainer); - } - isMounted = true; - app._container = rootContainer; - rootContainer.__vue_app__ = app; - if (process.env.NODE_ENV !== 'production' || __VUE_PROD_DEVTOOLS__) { - devtoolsInitApp(app, version); - } - return vnode.component.proxy - } else if (process.env.NODE_ENV !== 'production') { - warn( - `App has already been mounted.\n` + - `If you want to remount the same app, move your app creation logic ` + - `into a factory function and create fresh app instances for each ` + - `mount - e.g. \`const createMyApp = () => createApp(App)\`` - ); - } - }, - unmount() { - if (isMounted) { - render(null, app._container); - if (process.env.NODE_ENV !== 'production' || __VUE_PROD_DEVTOOLS__) { - devtoolsUnmountApp(app); - } - } else if (process.env.NODE_ENV !== 'production') { - warn(`Cannot unmount an app that is not mounted.`); - } - }, - provide(key, value) { - if (process.env.NODE_ENV !== 'production' && key in context.provides) { - warn( - `App already provides property with key "${String(key)}". ` + - `It will be overwritten with the new value.` - ); - } - // TypeScript doesn't allow symbols as index type - // https://github.com/Microsoft/TypeScript/issues/24587 - context.provides[key] = value; - return app - } - }); - return app - } +function createAppContext() { + return { + app: null, + config: { + isNativeTag: NO, + performance: false, + globalProperties: {}, + optionMergeStrategies: {}, + isCustomElement: NO, + errorHandler: undefined, + warnHandler: undefined + }, + mixins: [], + components: {}, + directives: {}, + provides: Object.create(null) + }; +} +let uid$1 = 0; +function createAppAPI(render, hydrate) { + return function createApp(rootComponent, rootProps = null) { + if (rootProps != null && !isObject(rootProps)) { + (process.env.NODE_ENV !== 'production') && warn(`root props passed to app.mount() must be an object.`); + rootProps = null; + } + const context = createAppContext(); + const installedPlugins = new Set(); + let isMounted = false; + const app = (context.app = { + _uid: uid$1++, + _component: rootComponent, + _props: rootProps, + _container: null, + _context: context, + version, + get config() { + return context.config; + }, + set config(v) { + if ((process.env.NODE_ENV !== 'production')) { + warn(`app.config cannot be replaced. Modify individual options instead.`); + } + }, + use(plugin, ...options) { + if (installedPlugins.has(plugin)) { + (process.env.NODE_ENV !== 'production') && warn(`Plugin has already been applied to target app.`); + } + else if (plugin && isFunction(plugin.install)) { + installedPlugins.add(plugin); + plugin.install(app, ...options); + } + else if (isFunction(plugin)) { + installedPlugins.add(plugin); + plugin(app, ...options); + } + else if ((process.env.NODE_ENV !== 'production')) { + warn(`A plugin must either be a function or an object with an "install" ` + + `function.`); + } + return app; + }, + mixin(mixin) { + if (__VUE_OPTIONS_API__) { + if (!context.mixins.includes(mixin)) { + context.mixins.push(mixin); + } + else if ((process.env.NODE_ENV !== 'production')) { + warn('Mixin has already been applied to target app' + + (mixin.name ? `: ${mixin.name}` : '')); + } + } + else if ((process.env.NODE_ENV !== 'production')) { + warn('Mixins are only available in builds supporting Options API'); + } + return app; + }, + component(name, component) { + if ((process.env.NODE_ENV !== 'production')) { + validateComponentName(name, context.config); + } + if (!component) { + return context.components[name]; + } + if ((process.env.NODE_ENV !== 'production') && context.components[name]) { + warn(`Component "${name}" has already been registered in target app.`); + } + context.components[name] = component; + return app; + }, + directive(name, directive) { + if ((process.env.NODE_ENV !== 'production')) { + validateDirectiveName(name); + } + if (!directive) { + return context.directives[name]; + } + if ((process.env.NODE_ENV !== 'production') && context.directives[name]) { + warn(`Directive "${name}" has already been registered in target app.`); + } + context.directives[name] = directive; + return app; + }, + mount(rootContainer, isHydrate) { + if (!isMounted) { + const vnode = createVNode(rootComponent, rootProps); + // store app context on the root VNode. + // this will be set on the root instance on initial mount. + vnode.appContext = context; + // HMR root reload + if ((process.env.NODE_ENV !== 'production')) { + context.reload = () => { + render(cloneVNode(vnode), rootContainer); + }; + } + if (isHydrate && hydrate) { + hydrate(vnode, rootContainer); + } + else { + render(vnode, rootContainer); + } + isMounted = true; + app._container = rootContainer; + rootContainer.__vue_app__ = app; + if ((process.env.NODE_ENV !== 'production') || __VUE_PROD_DEVTOOLS__) { + devtoolsInitApp(app, version); + } + return vnode.component.proxy; + } + else if ((process.env.NODE_ENV !== 'production')) { + warn(`App has already been mounted.\n` + + `If you want to remount the same app, move your app creation logic ` + + `into a factory function and create fresh app instances for each ` + + `mount - e.g. \`const createMyApp = () => createApp(App)\``); + } + }, + unmount() { + if (isMounted) { + render(null, app._container); + if ((process.env.NODE_ENV !== 'production') || __VUE_PROD_DEVTOOLS__) { + devtoolsUnmountApp(app); + } + } + else if ((process.env.NODE_ENV !== 'production')) { + warn(`Cannot unmount an app that is not mounted.`); + } + }, + provide(key, value) { + if ((process.env.NODE_ENV !== 'production') && key in context.provides) { + warn(`App already provides property with key "${String(key)}". ` + + `It will be overwritten with the new value.`); + } + // TypeScript doesn't allow symbols as index type + // https://github.com/Microsoft/TypeScript/issues/24587 + context.provides[key] = value; + return app; + } + }); + return app; + }; } -let hasMismatch = false; -const isSVGContainer = container => - /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject'; -const isComment = node => node.nodeType === 8; /* COMMENT */ -// Note: hydration is DOM-specific -// But we have to place it in core due to tight coupling with core - splitting -// it out creates a ton of unnecessary complexity. -// Hydration also depends on some renderer internal logic which needs to be -// passed in via arguments. -function createHydrationFunctions(rendererInternals) { - const { - mt: mountComponent, - p: patch, - o: { patchProp, nextSibling, parentNode, remove, insert, createComment } - } = rendererInternals; - const hydrate = (vnode, container) => { - if (process.env.NODE_ENV !== 'production' && !container.hasChildNodes()) { - warn( - `Attempting to hydrate existing markup but container is empty. ` + - `Performing full mount instead.` - ); - patch(null, vnode, container); - return - } - hasMismatch = false; - hydrateNode(container.firstChild, vnode, null, null); - flushPostFlushCbs(); - if (hasMismatch && !false) { - // this error should show up in production - console.error(`Hydration completed but contains mismatches.`); - } - }; - const hydrateNode = ( - node, - vnode, - parentComponent, - parentSuspense, - optimized = false - ) => { - const isFragmentStart = isComment(node) && node.data === '['; - const onMismatch = () => - handleMismatch( - node, - vnode, - parentComponent, - parentSuspense, - isFragmentStart - ); - const { type, ref, shapeFlag } = vnode; - const domType = node.nodeType; - vnode.el = node; - let nextNode = null; - switch (type) { - case Text: - if (domType !== 3 /* TEXT */) { - nextNode = onMismatch(); - } else { - if (node.data !== vnode.children) { - hasMismatch = true; - process.env.NODE_ENV !== 'production' && - warn( - `Hydration text mismatch:` + - `\n- Client: ${JSON.stringify(node.data)}` + - `\n- Server: ${JSON.stringify(vnode.children)}` - ); - node.data = vnode.children; - } - nextNode = nextSibling(node); - } - break - case Comment: - if (domType !== 8 /* COMMENT */ || isFragmentStart) { - nextNode = onMismatch(); - } else { - nextNode = nextSibling(node); - } - break - case Static: - if (domType !== 1 /* ELEMENT */) { - nextNode = onMismatch(); - } else { - // determine anchor, adopt content - nextNode = node; - // if the static vnode has its content stripped during build, - // adopt it from the server-rendered HTML. - const needToAdoptContent = !vnode.children.length; - for (let i = 0; i < vnode.staticCount; i++) { - if (needToAdoptContent) vnode.children += nextNode.outerHTML; - if (i === vnode.staticCount - 1) { - vnode.anchor = nextNode; - } - nextNode = nextSibling(nextNode); - } - return nextNode - } - break - case Fragment: - if (!isFragmentStart) { - nextNode = onMismatch(); - } else { - nextNode = hydrateFragment( - node, - vnode, - parentComponent, - parentSuspense, - optimized - ); - } - break - default: - if (shapeFlag & 1 /* ELEMENT */) { - if ( - domType !== 1 /* ELEMENT */ || - vnode.type !== node.tagName.toLowerCase() - ) { - nextNode = onMismatch(); - } else { - nextNode = hydrateElement( - node, - vnode, - parentComponent, - parentSuspense, - optimized - ); - } - } else if (shapeFlag & 6 /* COMPONENT */) { - // when setting up the render effect, if the initial vnode already - // has .el set, the component will perform hydration instead of mount - // on its sub-tree. - const container = parentNode(node); - const hydrateComponent = () => { - mountComponent( - vnode, - container, - null, - parentComponent, - parentSuspense, - isSVGContainer(container), - optimized - ); - }; - // async component - const loadAsync = vnode.type.__asyncLoader; - if (loadAsync) { - loadAsync().then(hydrateComponent); - } else { - hydrateComponent(); - } - // component may be async, so in the case of fragments we cannot rely - // on component's rendered output to determine the end of the fragment - // instead, we do a lookahead to find the end anchor node. - nextNode = isFragmentStart - ? locateClosingAsyncAnchor(node) - : nextSibling(node); - } else if (shapeFlag & 64 /* TELEPORT */) { - if (domType !== 8 /* COMMENT */) { - nextNode = onMismatch(); - } else { - nextNode = vnode.type.hydrate( - node, - vnode, - parentComponent, - parentSuspense, - optimized, - rendererInternals, - hydrateChildren - ); - } - } else if (shapeFlag & 128 /* SUSPENSE */) { - nextNode = vnode.type.hydrate( - node, - vnode, - parentComponent, - parentSuspense, - isSVGContainer(parentNode(node)), - optimized, - rendererInternals, - hydrateNode - ); - } else if (process.env.NODE_ENV !== 'production') { - warn('Invalid HostVNode type:', type, `(${typeof type})`); - } - } - if (ref != null && parentComponent) { - setRef(ref, null, parentComponent, parentSuspense, vnode); - } - return nextNode - }; - const hydrateElement = ( - el, - vnode, - parentComponent, - parentSuspense, - optimized - ) => { - optimized = optimized || !!vnode.dynamicChildren; - const { props, patchFlag, shapeFlag, dirs } = vnode; - // skip props & children if this is hoisted static nodes - if (patchFlag !== -1 /* HOISTED */) { - if (dirs) { - invokeDirectiveHook(vnode, null, parentComponent, 'created'); - } - // props - if (props) { - if ( - !optimized || - (patchFlag & 16 /* FULL_PROPS */ || - patchFlag & 32) /* HYDRATE_EVENTS */ - ) { - for (const key in props) { - if (!isReservedProp(key) && isOn(key)) { - patchProp(el, key, null, props[key]); - } - } - } else if (props.onClick) { - // Fast path for click listeners (which is most often) to avoid - // iterating through props. - patchProp(el, 'onClick', null, props.onClick); - } - } - // vnode / directive hooks - let vnodeHooks; - if ((vnodeHooks = props && props.onVnodeBeforeMount)) { - invokeVNodeHook(vnodeHooks, parentComponent, vnode); - } - if (dirs) { - invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount'); - } - if ((vnodeHooks = props && props.onVnodeMounted) || dirs) { - queueEffectWithSuspense(() => { - vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode); - dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted'); - }, parentSuspense); - } - // children - if ( - shapeFlag & 16 /* ARRAY_CHILDREN */ && - // skip if element has innerHTML / textContent - !(props && (props.innerHTML || props.textContent)) - ) { - let next = hydrateChildren( - el.firstChild, - vnode, - el, - parentComponent, - parentSuspense, - optimized - ); - let hasWarned = false; - while (next) { - hasMismatch = true; - if (process.env.NODE_ENV !== 'production' && !hasWarned) { - warn( - `Hydration children mismatch in <${vnode.type}>: ` + - `server rendered element contains more child nodes than client vdom.` - ); - hasWarned = true; - } - // The SSRed DOM contains more nodes than it should. Remove them. - const cur = next; - next = next.nextSibling; - remove(cur); - } - } else if (shapeFlag & 8 /* TEXT_CHILDREN */) { - if (el.textContent !== vnode.children) { - hasMismatch = true; - process.env.NODE_ENV !== 'production' && - warn( - `Hydration text content mismatch in <${vnode.type}>:\n` + - `- Client: ${el.textContent}\n` + - `- Server: ${vnode.children}` - ); - el.textContent = vnode.children; - } - } - } - return el.nextSibling - }; - const hydrateChildren = ( - node, - vnode, - container, - parentComponent, - parentSuspense, - optimized - ) => { - optimized = optimized || !!vnode.dynamicChildren; - const children = vnode.children; - const l = children.length; - let hasWarned = false; - for (let i = 0; i < l; i++) { - const vnode = optimized - ? children[i] - : (children[i] = normalizeVNode(children[i])); - if (node) { - node = hydrateNode( - node, - vnode, - parentComponent, - parentSuspense, - optimized - ); - } else { - hasMismatch = true; - if (process.env.NODE_ENV !== 'production' && !hasWarned) { - warn( - `Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` + - `server rendered element contains fewer child nodes than client vdom.` - ); - hasWarned = true; - } - // the SSRed DOM didn't contain enough nodes. Mount the missing ones. - patch( - null, - vnode, - container, - null, - parentComponent, - parentSuspense, - isSVGContainer(container) - ); - } - } - return node - }; - const hydrateFragment = ( - node, - vnode, - parentComponent, - parentSuspense, - optimized - ) => { - const container = parentNode(node); - const next = hydrateChildren( - nextSibling(node), - vnode, - container, - parentComponent, - parentSuspense, - optimized - ); - if (next && isComment(next) && next.data === ']') { - return nextSibling((vnode.anchor = next)) - } else { - // fragment didn't hydrate successfully, since we didn't get a end anchor - // back. This should have led to node/children mismatch warnings. - hasMismatch = true; - // since the anchor is missing, we need to create one and insert it - insert((vnode.anchor = createComment(`]`)), container, next); - return next - } - }; - const handleMismatch = ( - node, - vnode, - parentComponent, - parentSuspense, - isFragment - ) => { - hasMismatch = true; - process.env.NODE_ENV !== 'production' && - warn( - `Hydration node mismatch:\n- Client vnode:`, - vnode.type, - `\n- Server rendered DOM:`, - node, - node.nodeType === 3 /* TEXT */ - ? `(text)` - : isComment(node) && node.data === '[' - ? `(start of fragment)` - : `` - ); - vnode.el = null; - if (isFragment) { - // remove excessive fragment nodes - const end = locateClosingAsyncAnchor(node); - while (true) { - const next = nextSibling(node); - if (next && next !== end) { - remove(next); - } else { - break - } - } - } - const next = nextSibling(node); - const container = parentNode(node); - remove(node); - patch( - null, - vnode, - container, - next, - parentComponent, - parentSuspense, - isSVGContainer(container) - ); - return next - }; - const locateClosingAsyncAnchor = node => { - let match = 0; - while (node) { - node = nextSibling(node); - if (node && isComment(node)) { - if (node.data === '[') match++; - if (node.data === ']') { - if (match === 0) { - return nextSibling(node) - } else { - match--; - } - } - } - } - return node - }; - return [hydrate, hydrateNode] +let hasMismatch = false; +const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject'; +const isComment = (node) => node.nodeType === 8 /* COMMENT */; +// Note: hydration is DOM-specific +// But we have to place it in core due to tight coupling with core - splitting +// it out creates a ton of unnecessary complexity. +// Hydration also depends on some renderer internal logic which needs to be +// passed in via arguments. +function createHydrationFunctions(rendererInternals) { + const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals; + const hydrate = (vnode, container) => { + if ((process.env.NODE_ENV !== 'production') && !container.hasChildNodes()) { + warn(`Attempting to hydrate existing markup but container is empty. ` + + `Performing full mount instead.`); + patch(null, vnode, container); + return; + } + hasMismatch = false; + hydrateNode(container.firstChild, vnode, null, null); + flushPostFlushCbs(); + if (hasMismatch && !false) { + // this error should show up in production + console.error(`Hydration completed but contains mismatches.`); + } + }; + const hydrateNode = (node, vnode, parentComponent, parentSuspense, optimized = false) => { + const isFragmentStart = isComment(node) && node.data === '['; + const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, isFragmentStart); + const { type, ref, shapeFlag } = vnode; + const domType = node.nodeType; + vnode.el = node; + let nextNode = null; + switch (type) { + case Text: + if (domType !== 3 /* TEXT */) { + nextNode = onMismatch(); + } + else { + if (node.data !== vnode.children) { + hasMismatch = true; + (process.env.NODE_ENV !== 'production') && + warn(`Hydration text mismatch:` + + `\n- Client: ${JSON.stringify(node.data)}` + + `\n- Server: ${JSON.stringify(vnode.children)}`); + node.data = vnode.children; + } + nextNode = nextSibling(node); + } + break; + case Comment: + if (domType !== 8 /* COMMENT */ || isFragmentStart) { + nextNode = onMismatch(); + } + else { + nextNode = nextSibling(node); + } + break; + case Static: + if (domType !== 1 /* ELEMENT */) { + nextNode = onMismatch(); + } + else { + // determine anchor, adopt content + nextNode = node; + // if the static vnode has its content stripped during build, + // adopt it from the server-rendered HTML. + const needToAdoptContent = !vnode.children.length; + for (let i = 0; i < vnode.staticCount; i++) { + if (needToAdoptContent) + vnode.children += nextNode.outerHTML; + if (i === vnode.staticCount - 1) { + vnode.anchor = nextNode; + } + nextNode = nextSibling(nextNode); + } + return nextNode; + } + break; + case Fragment: + if (!isFragmentStart) { + nextNode = onMismatch(); + } + else { + nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, optimized); + } + break; + default: + if (shapeFlag & 1 /* ELEMENT */) { + if (domType !== 1 /* ELEMENT */ || + vnode.type !== node.tagName.toLowerCase()) { + nextNode = onMismatch(); + } + else { + nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, optimized); + } + } + else if (shapeFlag & 6 /* COMPONENT */) { + // when setting up the render effect, if the initial vnode already + // has .el set, the component will perform hydration instead of mount + // on its sub-tree. + const container = parentNode(node); + const hydrateComponent = () => { + mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized); + }; + // async component + const loadAsync = vnode.type.__asyncLoader; + if (loadAsync) { + loadAsync().then(hydrateComponent); + } + else { + hydrateComponent(); + } + // component may be async, so in the case of fragments we cannot rely + // on component's rendered output to determine the end of the fragment + // instead, we do a lookahead to find the end anchor node. + nextNode = isFragmentStart + ? locateClosingAsyncAnchor(node) + : nextSibling(node); + } + else if (shapeFlag & 64 /* TELEPORT */) { + if (domType !== 8 /* COMMENT */) { + nextNode = onMismatch(); + } + else { + nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, optimized, rendererInternals, hydrateChildren); + } + } + else if ( shapeFlag & 128 /* SUSPENSE */) { + nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), optimized, rendererInternals, hydrateNode); + } + else if ((process.env.NODE_ENV !== 'production')) { + warn('Invalid HostVNode type:', type, `(${typeof type})`); + } + } + if (ref != null && parentComponent) { + setRef(ref, null, parentComponent, parentSuspense, vnode); + } + return nextNode; + }; + const hydrateElement = (el, vnode, parentComponent, parentSuspense, optimized) => { + optimized = optimized || !!vnode.dynamicChildren; + const { props, patchFlag, shapeFlag, dirs } = vnode; + // skip props & children if this is hoisted static nodes + if (patchFlag !== -1 /* HOISTED */) { + if (dirs) { + invokeDirectiveHook(vnode, null, parentComponent, 'created'); + } + // props + if (props) { + if (!optimized || + (patchFlag & 16 /* FULL_PROPS */ || + patchFlag & 32 /* HYDRATE_EVENTS */)) { + for (const key in props) { + if (!isReservedProp(key) && isOn(key)) { + patchProp(el, key, null, props[key]); + } + } + } + else if (props.onClick) { + // Fast path for click listeners (which is most often) to avoid + // iterating through props. + patchProp(el, 'onClick', null, props.onClick); + } + } + // vnode / directive hooks + let vnodeHooks; + if ((vnodeHooks = props && props.onVnodeBeforeMount)) { + invokeVNodeHook(vnodeHooks, parentComponent, vnode); + } + if (dirs) { + invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount'); + } + if ((vnodeHooks = props && props.onVnodeMounted) || dirs) { + queueEffectWithSuspense(() => { + vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode); + dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted'); + }, parentSuspense); + } + // children + if (shapeFlag & 16 /* ARRAY_CHILDREN */ && + // skip if element has innerHTML / textContent + !(props && (props.innerHTML || props.textContent))) { + let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, optimized); + let hasWarned = false; + while (next) { + hasMismatch = true; + if ((process.env.NODE_ENV !== 'production') && !hasWarned) { + warn(`Hydration children mismatch in <${vnode.type}>: ` + + `server rendered element contains more child nodes than client vdom.`); + hasWarned = true; + } + // The SSRed DOM contains more nodes than it should. Remove them. + const cur = next; + next = next.nextSibling; + remove(cur); + } + } + else if (shapeFlag & 8 /* TEXT_CHILDREN */) { + if (el.textContent !== vnode.children) { + hasMismatch = true; + (process.env.NODE_ENV !== 'production') && + warn(`Hydration text content mismatch in <${vnode.type}>:\n` + + `- Client: ${el.textContent}\n` + + `- Server: ${vnode.children}`); + el.textContent = vnode.children; + } + } + } + return el.nextSibling; + }; + const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, optimized) => { + optimized = optimized || !!parentVNode.dynamicChildren; + const children = parentVNode.children; + const l = children.length; + let hasWarned = false; + for (let i = 0; i < l; i++) { + const vnode = optimized + ? children[i] + : (children[i] = normalizeVNode(children[i])); + if (node) { + node = hydrateNode(node, vnode, parentComponent, parentSuspense, optimized); + } + else { + hasMismatch = true; + if ((process.env.NODE_ENV !== 'production') && !hasWarned) { + warn(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` + + `server rendered element contains fewer child nodes than client vdom.`); + hasWarned = true; + } + // the SSRed DOM didn't contain enough nodes. Mount the missing ones. + patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container)); + } + } + return node; + }; + const hydrateFragment = (node, vnode, parentComponent, parentSuspense, optimized) => { + const container = parentNode(node); + const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, optimized); + if (next && isComment(next) && next.data === ']') { + return nextSibling((vnode.anchor = next)); + } + else { + // fragment didn't hydrate successfully, since we didn't get a end anchor + // back. This should have led to node/children mismatch warnings. + hasMismatch = true; + // since the anchor is missing, we need to create one and insert it + insert((vnode.anchor = createComment(`]`)), container, next); + return next; + } + }; + const handleMismatch = (node, vnode, parentComponent, parentSuspense, isFragment) => { + hasMismatch = true; + (process.env.NODE_ENV !== 'production') && + warn(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */ + ? `(text)` + : isComment(node) && node.data === '[' + ? `(start of fragment)` + : ``); + vnode.el = null; + if (isFragment) { + // remove excessive fragment nodes + const end = locateClosingAsyncAnchor(node); + while (true) { + const next = nextSibling(node); + if (next && next !== end) { + remove(next); + } + else { + break; + } + } + } + const next = nextSibling(node); + const container = parentNode(node); + remove(node); + patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container)); + return next; + }; + const locateClosingAsyncAnchor = (node) => { + let match = 0; + while (node) { + node = nextSibling(node); + if (node && isComment(node)) { + if (node.data === '[') + match++; + if (node.data === ']') { + if (match === 0) { + return nextSibling(node); + } + else { + match--; + } + } + } + } + return node; + }; + return [hydrate, hydrateNode]; } -let supported; -let perf; -function startMeasure(instance, type) { - if (instance.appContext.config.performance && isSupported()) { - perf.mark(`vue-${type}-${instance.uid}`); - } -} -function endMeasure(instance, type) { - if (instance.appContext.config.performance && isSupported()) { - const startTag = `vue-${type}-${instance.uid}`; - const endTag = startTag + `:end`; - perf.mark(endTag); - perf.measure( - `<${formatComponentName(instance, instance.type)}> ${type}`, - startTag, - endTag - ); - perf.clearMarks(startTag); - perf.clearMarks(endTag); - } -} -function isSupported() { - if (supported !== undefined) { - return supported - } - /* eslint-disable no-restricted-globals */ - if (typeof window !== 'undefined' && window.performance) { - supported = true; - perf = window.performance; - } else { - supported = false; - } - /* eslint-enable no-restricted-globals */ - return supported +let supported; +let perf; +function startMeasure(instance, type) { + if (instance.appContext.config.performance && isSupported()) { + perf.mark(`vue-${type}-${instance.uid}`); + } +} +function endMeasure(instance, type) { + if (instance.appContext.config.performance && isSupported()) { + const startTag = `vue-${type}-${instance.uid}`; + const endTag = startTag + `:end`; + perf.mark(endTag); + perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag); + perf.clearMarks(startTag); + perf.clearMarks(endTag); + } +} +function isSupported() { + if (supported !== undefined) { + return supported; + } + /* eslint-disable no-restricted-globals */ + if (typeof window !== 'undefined' && window.performance) { + supported = true; + perf = window.performance; + } + else { + supported = false; + } + /* eslint-enable no-restricted-globals */ + return supported; } -/** - * This is only called in esm-bundler builds. - * It is called when a renderer is created, in `baseCreateRenderer` so that - * importing runtime-core is side-effects free. - * - * istanbul-ignore-next - */ -function initFeatureFlags() { - let needWarn = false; - if (typeof __VUE_OPTIONS_API__ !== 'boolean') { - needWarn = true; - getGlobalThis().__VUE_OPTIONS_API__ = true; - } - if (typeof __VUE_PROD_DEVTOOLS__ !== 'boolean') { - needWarn = true; - getGlobalThis().__VUE_PROD_DEVTOOLS__ = false; - } - if (process.env.NODE_ENV !== 'production' && needWarn) { - console.warn( - `You are running the esm-bundler build of Vue. It is recommended to ` + - `configure your bundler to explicitly replace feature flag globals ` + - `with boolean literals to get proper tree-shaking in the final bundle. ` + - `See http://link.vuejs.org/feature-flags for more details.` - ); - } +/** + * This is only called in esm-bundler builds. + * It is called when a renderer is created, in `baseCreateRenderer` so that + * importing runtime-core is side-effects free. + * + * istanbul-ignore-next + */ +function initFeatureFlags() { + let needWarn = false; + if (typeof __VUE_OPTIONS_API__ !== 'boolean') { + needWarn = true; + getGlobalThis().__VUE_OPTIONS_API__ = true; + } + if (typeof __VUE_PROD_DEVTOOLS__ !== 'boolean') { + needWarn = true; + getGlobalThis().__VUE_PROD_DEVTOOLS__ = false; + } + if ((process.env.NODE_ENV !== 'production') && needWarn) { + console.warn(`You are running the esm-bundler build of Vue. It is recommended to ` + + `configure your bundler to explicitly replace feature flag globals ` + + `with boolean literals to get proper tree-shaking in the final bundle. ` + + `See http://link.vuejs.org/feature-flags for more details.`); + } } -const prodEffectOptions = { - scheduler: queueJob -}; -function createDevEffectOptions(instance) { - return { - scheduler: queueJob, - onTrack: instance.rtc ? e => invokeArrayFns(instance.rtc, e) : void 0, - onTrigger: instance.rtg ? e => invokeArrayFns(instance.rtg, e) : void 0 - } -} -const queuePostRenderEffect = queueEffectWithSuspense; -const setRef = (rawRef, oldRawRef, parentComponent, parentSuspense, vnode) => { - let value; - if (!vnode) { - value = null; - } else { - if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) { - value = vnode.component.proxy; - } else { - value = vnode.el; - } - } - const [owner, ref] = rawRef; - if (process.env.NODE_ENV !== 'production' && !owner) { - warn( - `Missing ref owner context. ref cannot be used on hoisted vnodes. ` + - `A vnode with ref must be created inside the render function.` - ); - return - } - const oldRef = oldRawRef && oldRawRef[1]; - const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs; - const setupState = owner.setupState; - // unset old ref - if (oldRef != null && oldRef !== ref) { - if (isString(oldRef)) { - refs[oldRef] = null; - if (hasOwn(setupState, oldRef)) { - setupState[oldRef] = null; - } - } else if (isRef(oldRef)) { - oldRef.value = null; - } - } - if (isString(ref)) { - const doSet = () => { - refs[ref] = value; - if (hasOwn(setupState, ref)) { - setupState[ref] = value; - } - }; - // #1789: for non-null values, set them after render - // null values means this is unmount and it should not overwrite another - // ref with the same key - if (value) { - doSet.id = -1; - queuePostRenderEffect(doSet, parentSuspense); - } else { - doSet(); - } - } else if (isRef(ref)) { - const doSet = () => { - ref.value = value; - }; - if (value) { - doSet.id = -1; - queuePostRenderEffect(doSet, parentSuspense); - } else { - doSet(); - } - } else if (isFunction(ref)) { - callWithErrorHandling(ref, parentComponent, 12 /* FUNCTION_REF */, [ - value, - refs - ]); - } else if (process.env.NODE_ENV !== 'production') { - warn('Invalid template ref type:', value, `(${typeof value})`); - } -}; -/** - * The createRenderer function accepts two generic arguments: - * HostNode and HostElement, corresponding to Node and Element types in the - * host environment. For example, for runtime-dom, HostNode would be the DOM - * `Node` interface and HostElement would be the DOM `Element` interface. - * - * Custom renderers can pass in the platform specific types like this: - * - * ``` js - * const { render, createApp } = createRenderer({ - * patchProp, - * ...nodeOps - * }) - * ``` - */ -function createRenderer(options) { - return baseCreateRenderer(options) -} -// Separate API for creating hydration-enabled renderer. -// Hydration logic is only used when calling this function, making it -// tree-shakable. -function createHydrationRenderer(options) { - return baseCreateRenderer(options, createHydrationFunctions) -} -// implementation -function baseCreateRenderer(options, createHydrationFns) { - // compile-time feature flags check - { - initFeatureFlags(); - } - const { - insert: hostInsert, - remove: hostRemove, - patchProp: hostPatchProp, - forcePatchProp: hostForcePatchProp, - createElement: hostCreateElement, - createText: hostCreateText, - createComment: hostCreateComment, - setText: hostSetText, - setElementText: hostSetElementText, - parentNode: hostParentNode, - nextSibling: hostNextSibling, - setScopeId: hostSetScopeId = NOOP, - cloneNode: hostCloneNode, - insertStaticContent: hostInsertStaticContent - } = options; - // Note: functions inside this closure should use `const xxx = () => {}` - // style in order to prevent being inlined by minifiers. - const patch = ( - n1, - n2, - container, - anchor = null, - parentComponent = null, - parentSuspense = null, - isSVG = false, - optimized = false - ) => { - // patching & not same type, unmount old tree - if (n1 && !isSameVNodeType(n1, n2)) { - anchor = getNextHostNode(n1); - unmount(n1, parentComponent, parentSuspense, true); - n1 = null; - } - if (n2.patchFlag === -2 /* BAIL */) { - optimized = false; - n2.dynamicChildren = null; - } - const { type, ref, shapeFlag } = n2; - switch (type) { - case Text: - processText(n1, n2, container, anchor); - break - case Comment: - processCommentNode(n1, n2, container, anchor); - break - case Static: - if (n1 == null) { - mountStaticNode(n2, container, anchor, isSVG); - } else if (process.env.NODE_ENV !== 'production') { - patchStaticNode(n1, n2, container, isSVG); - } - break - case Fragment: - processFragment( - n1, - n2, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized - ); - break - default: - if (shapeFlag & 1 /* ELEMENT */) { - processElement( - n1, - n2, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized - ); - } else if (shapeFlag & 6 /* COMPONENT */) { - processComponent( - n1, - n2, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized - ); - } else if (shapeFlag & 64 /* TELEPORT */) { - type.process( - n1, - n2, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized, - internals - ); - } else if (shapeFlag & 128 /* SUSPENSE */) { - type.process( - n1, - n2, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized, - internals - ); - } else if (process.env.NODE_ENV !== 'production') { - warn('Invalid VNode type:', type, `(${typeof type})`); - } - } - // set ref - if (ref != null && parentComponent) { - setRef(ref, n1 && n1.ref, parentComponent, parentSuspense, n2); - } - }; - const processText = (n1, n2, container, anchor) => { - if (n1 == null) { - hostInsert((n2.el = hostCreateText(n2.children)), container, anchor); - } else { - const el = (n2.el = n1.el); - if (n2.children !== n1.children) { - hostSetText(el, n2.children); - } - } - }; - const processCommentNode = (n1, n2, container, anchor) => { - if (n1 == null) { - hostInsert( - (n2.el = hostCreateComment(n2.children || '')), - container, - anchor - ); - } else { - // there's no support for dynamic comments - n2.el = n1.el; - } - }; - const mountStaticNode = (n2, container, anchor, isSVG) => { -[n2.el, n2.anchor] = hostInsertStaticContent( - n2.children, - container, - anchor, - isSVG - ); - }; - /** - * Dev / HMR only - */ - const patchStaticNode = (n1, n2, container, isSVG) => { - // static nodes are only patched during dev for HMR - if (n2.children !== n1.children) { - const anchor = hostNextSibling(n1.anchor); - // remove existing - removeStaticNode(n1) - ;[n2.el, n2.anchor] = hostInsertStaticContent( - n2.children, - container, - anchor, - isSVG - ); - } else { - n2.el = n1.el; - n2.anchor = n1.anchor; - } - }; - /** - * Dev / HMR only - */ - const moveStaticNode = (vnode, container, anchor) => { - let cur = vnode.el; - const end = vnode.anchor; - while (cur && cur !== end) { - const next = hostNextSibling(cur); - hostInsert(cur, container, anchor); - cur = next; - } - hostInsert(end, container, anchor); - }; - /** - * Dev / HMR only - */ - const removeStaticNode = vnode => { - let cur = vnode.el; - while (cur && cur !== vnode.anchor) { - const next = hostNextSibling(cur); - hostRemove(cur); - cur = next; - } - hostRemove(vnode.anchor); - }; - const processElement = ( - n1, - n2, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized - ) => { - isSVG = isSVG || n2.type === 'svg'; - if (n1 == null) { - mountElement( - n2, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized - ); - } else { - patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized); - } - }; - const mountElement = ( - vnode, - container, - anchor, - parentComponent, - parentSuspense, - isSVG, - optimized - ) => { - let el; - let vnodeHook; - const { - type, - props, - shapeFlag, - transition, - scopeId, - patchFlag, - dirs - } = vnode; - if ( - !(process.env.NODE_ENV !== 'production') && - vnode.el && - hostCloneNode !== undefined && - patchFlag === -1 /* HOISTED */ - ) { - // If a vnode has non-null el, it means it's being reused. - // Only static vnodes can be reused, so its mounted DOM nodes should be - // exactly the same, and we can simply do a clone here. - // only do this in production since cloned trees cannot be HMR updated. - el = vnode.el = hostCloneNode(vnode.el); - } else { - el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is); - // mount children first, since some props may rely on child content - // being already rendered, e.g. `