import Vue from './instance/index'
import { initGlobalAPI } from './global-api/index'
import { isServerRendering } from 'core/util/env'
import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
initGlobalAPI(Vue)
Object.defineProperty(Vue.prototype,'$isServer',{
get:isServerRendering
})
Object.defineProperty(Vue.prototype,'$ssrContext',{
get(){
return this.$vnode && this.$vnode.ssrContext
}
})
Object.defineProperty(Vue,'FunctionalRenderContext',{
value:FunctionalRenderContext
})
Vue.version = '__VERSION__'
export default Vue
isServerRendering
let _isServer
export const isServerRendering = () => {
if(_isServer === undefined){
if(!isBrowser && !inWeex && typeof global !== undefined){
_isServer = global['process'] && global['process'].env.VUE_ENV === 'server'
}else{
_isServer = false
}
}
}
FunctionalRenderContext
export function FunctionalRenderContext(data,props,children,parent,Ctor){
const options = Ctor.options
let contextVm
if(hasOwn(parent,'_uid')){
contextVm = Object.create(parent)
contextVm._original = parent
}else{
contextVm = parent
parent = parent._original
}
const isCompiled = isTrue(options._compiled)
const needNormalization = !isCompiled
this.data = data
this.props = props
this.children = children
this.parent = parent
this.listeners = data.on || emptyObject
this.injections = resolveInject(options.inject,parent)
this.slots = () => {
if(!this.$slots){
normalizeScopeSlots(
data.scopeSlots,
this.$slots = resolveSlots(children,parent)
)
}
return this.$slots
}
Object.define(this,'scopedSlots',({
enumerable: true,
get(){
return normalizeScopedSlots(data.scopeSlots,this.slots())
}
})
if(isCompiled){
this.$options = options
this.$slots = this.slots()
this.$scopedSlots = normalizeScopedSlots(data.scopedSlots,this.$slots)
}
if(options._scopeId){
this._c = (a,b,c,d)=>{
const vnode = createElement(contextVm,a,b,c,d,needNormalization)
if( vnode && !Array.isArray(vnode)){
vnode.fnScopeId = options._scopeId
vnode.fnContext = parent
}
return vnode
}
}else{
this._c = (a,b,c,d) => createElement(contextVm,a,b,c,d,needNormalization)
}
}
createElement
export function createElement(context,tag,data,children,normalizationType,alwaysNormalize){
if(Array.isArray(data) || isPrimitive(data)){
normalizationType = children
children = data
data = undefined
}
if(isTrue(alwaysNormalize)){
normalizationType = ALWAYS_NORMALIZE
}
return _createElement(context,tag,data,children,normalizationType)
}
export function _createElement(context,tag,data,children,normalizationType){
if(isDef(data) && isDef(data.__ob__)){
...
}
if(isDef(data) && isDef(data.is)){
tag = data.is
}
if(!tag){
return createEmptyVNode()
}
...
if(Array.isArray(children) && typeof children[0] === 'function'){
data = data || {}
data.scopedSlots = { default: children[0] }
children.length = 0
}
if(normalizeType === ALWAYS_NORMALIZE){
children = normalizeChildren(children)
}else if(normalizeType === SIMPLE_NORMALIZE){
children = simpleNormalizeChildren(children)
}
let vnode,ns
if(typeof tag === 'string'){
let Ctor
ns = (context.$vnode && context.$vnode.ns) || config.getTagNameSpace(tag)
if(config.isReservedTag(tag)){
...
vnode = new VNode(config.parsePlatformTagName(tag),data,children,null,null,context)
}else if((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options,'components',tag))){
vnode = createComponent(Ctor,data,context,children,tag)
}else{
vnode = new VNode(tag,data,children,undefined,undefined,context)
}
}else{
vnode = createComponent(tag,data,context,children)
}
if(Array.isArray(vnode)){
return vnode
}else if(isDef(vnode)){
if(isDef(ns)) applyNs(vnode,ns)
if(isDef(data)) registerDeepBindings(data)
return vnode
}else{
return createEmptyVNode()
}
}
createComponent
export function createComponent(Ctor,data,context,children,tag){
if(isUndef(Ctor)){
return
}
const baseCtor = Ctor.$options._base
if(isObject(Ctor)){
Ctor = baseCtor.extend(Ctor)
}
if(typeof Ctor !== 'function'){
...
}
let asyncFactory
if(isUndef(Ctor.cid)){
asyncFactory = Ctor
Ctor = resolveAsyncComponent(asyncFactory,baseCtor)
if(Ctor === undefined){
return createAsyncPlaceholder(asyncFactory,data,context,children,tag,)
}
}
data = data || {}
resolveConstructorOptions(Ctor)
if(isDef(data.model)){
transformModel(Ctor.options,data)
}
const propsData = extractPropsFormVNodeData(data,Ctor,tag)
if(isTrue(Ctor.options.functional)){
return createFunctionalComponent(Ctor,propsData,data,context,children)
}
const listeners = data.on
data.on = data.nativeOn
if(isTrue(Ctor.options.abstract)){
const slot = data.slot
data = {}
if(slot){
data.slot = slot
}
}
installComponentHooks(data)
const name = Ctor.options.name || tag
const vnode = new VNode(`vue-component-${Ctor.cid}${name ? `-${name}`:''}`,data,undefined,undefined,undefined,context,{Ctor,propsData,listeners,tag,children},asyncFactory)
...
return vnode
}
resolveInject
export function resolveInject(inject,vm){
if(inject){
const result = Object.create(null)
const keys = hasSymbol ? Reflect.ownKeys(inject) : Object.keys(inject)
for(let i = 0; i < keys.length; i ++){
const key = keys[i]
if(key === '__ob__') continue
const provideKey = inject[key].from
let source = vm
while(source){
if(source._provided && hasOwn(source._provided,providedKey)){
result[key] = source._provided[providedKey]
break
}
source = source.$parent
}
if(!source){
if('default' in inject[key]){
const provideDefault = inject[key].default
result[key] = typeof provideDefault === 'function' ? provideDefault.call(vm) : provideDefault
}else if(process.env.NODE_ENV !== 'production'){
warn(`Injection "${key}" not found`,vm)
}
}
}
return result
}
}