2019-11-01 23:32:53 +08:00
import {
type App ,
2020-02-14 14:30:08 +08:00
type CreateAppFunction ,
2024-04-25 16:04:03 +08:00
type DefineComponent ,
2021-04-07 23:22:56 +08:00
DeprecationTypes ,
2024-04-25 16:04:03 +08:00
type Directive ,
2023-12-08 18:25:01 +08:00
type ElementNamespace ,
2020-02-15 01:33:32 +08:00
type HydrationRenderer ,
2021-04-03 23:55:44 +08:00
type Renderer ,
2021-02-25 05:18:55 +08:00
type RootHydrateFunction ,
2020-01-24 04:05:38 +08:00
type RootRenderFunction ,
2023-12-08 18:25:01 +08:00
compatUtils ,
createHydrationRenderer ,
2019-11-01 23:32:53 +08:00
createRenderer ,
2023-12-08 18:25:01 +08:00
isRuntimeOnly ,
2023-12-26 19:39:47 +08:00
warn ,
2019-11-01 23:32:53 +08:00
} from '@vue/runtime-core'
2019-06-20 21:28:37 +08:00
import { nodeOps } from './nodeOps'
2021-07-22 04:38:01 +08:00
import { patchProp } from './patchProp'
2019-10-22 04:25:16 +08:00
// Importing from the compiler, will be tree-shaken in prod
2021-09-24 03:02:19 +08:00
import {
2023-12-26 19:39:47 +08:00
NOOP ,
extend ,
2021-09-24 03:02:19 +08:00
isFunction ,
isHTMLTag ,
2023-12-08 18:25:01 +08:00
isMathMLTag ,
2021-09-24 03:02:19 +08:00
isSVGTag ,
2023-12-08 18:25:01 +08:00
isString ,
2021-09-24 03:02:19 +08:00
} from '@vue/shared'
2024-04-25 16:04:03 +08:00
import type { TransitionProps } from './components/Transition'
import type { TransitionGroupProps } from './components/TransitionGroup'
import type { vShow } from './directives/vShow'
import type { VOnDirective } from './directives/vOn'
import type { VModelDirective } from './directives/vModel'
2018-09-19 23:35:38 +08:00
2024-08-13 22:06:10 +08:00
/ * *
* This is a stub implementation to prevent the need to use dom types .
*
* To enable proper types , add ` "dom" ` to ` "lib" ` in your ` tsconfig.json ` .
* /
type DomStub = { }
type DomType < T > = typeof globalThis extends { window : unknown } ? T : DomStub
2020-05-02 04:14:30 +08:00
declare module '@vue/reactivity' {
export interface RefUnwrapBailTypes {
2024-08-13 22:06:10 +08:00
runtimeDOMBailTypes : DomType < Node | Window >
2020-05-02 04:14:30 +08:00
}
}
2024-04-25 16:04:03 +08:00
declare module '@vue/runtime-core' {
interface GlobalComponents {
Transition : DefineComponent < TransitionProps >
TransitionGroup : DefineComponent < TransitionGroupProps >
}
interface GlobalDirectives {
vShow : typeof vShow
vOn : VOnDirective
vBind : VModelDirective
vIf : Directive < any , boolean >
VOnce : Directive
VSlot : Directive
}
}
2024-09-04 20:24:33 +08:00
const rendererOptions = /*@__PURE__*/ extend ( { patchProp } , nodeOps )
2020-02-14 14:30:08 +08:00
// lazy create the renderer - this makes core renderer logic tree-shakable
// in case the user only imports reactivity utilities from Vue.
2021-07-13 03:32:38 +08:00
let renderer : Renderer < Element | ShadowRoot > | HydrationRenderer
2020-02-14 14:30:08 +08:00
let enabledHydration = false
function ensureRenderer() {
2021-07-13 03:32:38 +08:00
return (
renderer ||
( renderer = createRenderer < Node , Element | ShadowRoot > ( rendererOptions ) )
)
2020-02-14 14:30:08 +08:00
}
function ensureHydrationRenderer() {
renderer = enabledHydration
? renderer
: createHydrationRenderer ( rendererOptions )
enabledHydration = true
2020-02-15 01:33:32 +08:00
return renderer as HydrationRenderer
2020-02-14 14:30:08 +08:00
}
2019-09-03 04:09:34 +08:00
2019-11-01 23:32:53 +08:00
// use explicit type casts here to avoid import() calls in rolled-up d.ts
2020-02-14 14:30:08 +08:00
export const render = ( ( . . . args ) = > {
ensureRenderer ( ) . render ( . . . args )
2021-07-13 03:32:38 +08:00
} ) as RootRenderFunction < Element | ShadowRoot >
2020-02-14 14:30:08 +08:00
export const hydrate = ( ( . . . args ) = > {
ensureHydrationRenderer ( ) . hydrate ( . . . args )
2020-02-15 01:33:32 +08:00
} ) as RootHydrateFunction
2019-11-01 23:32:53 +08:00
2020-02-14 14:30:08 +08:00
export const createApp = ( ( . . . args ) = > {
const app = ensureRenderer ( ) . createApp ( . . . args )
2019-10-25 09:58:34 +08:00
if ( __DEV__ ) {
2020-02-14 14:30:08 +08:00
injectNativeTagCheck ( app )
2021-04-26 23:46:29 +08:00
injectCompilerOptionsCheck ( app )
2019-10-25 09:58:34 +08:00
}
2020-01-24 04:05:38 +08:00
const { mount } = app
2020-12-05 05:51:38 +08:00
app . mount = ( containerOrSelector : Element | ShadowRoot | string ) : any = > {
2020-02-14 14:30:08 +08:00
const container = normalizeContainer ( containerOrSelector )
if ( ! container ) return
2021-04-03 23:55:44 +08:00
2020-01-24 10:01:56 +08:00
const component = app . _component
2020-03-12 04:39:26 +08:00
if ( ! isFunction ( component ) && ! component . render && ! component . template ) {
2021-04-03 23:55:44 +08:00
// __UNSAFE__
// Reason: potential execution of JS expressions in in-DOM template.
// The user must make sure the in-DOM template is trusted. If it's
// rendered by the server, the template should not contain any user data.
2019-10-25 09:58:34 +08:00
component . template = container . innerHTML
2021-04-05 23:54:35 +08:00
// 2.x compat check
2024-08-07 16:07:47 +08:00
if ( __COMPAT__ && __DEV__ && container . nodeType === 1 ) {
for ( let i = 0 ; i < ( container as Element ) . attributes . length ; i ++ ) {
const attr = ( container as Element ) . attributes [ i ]
2021-04-05 23:54:35 +08:00
if ( attr . name !== 'v-cloak' && /^(v-|:|@)/ . test ( attr . name ) ) {
2021-04-10 11:21:13 +08:00
compatUtils . warnDeprecation (
DeprecationTypes . GLOBAL_MOUNT_CONTAINER ,
null ,
)
2021-04-05 23:54:35 +08:00
break
}
}
}
2019-10-25 09:58:34 +08:00
}
2021-04-05 23:54:35 +08:00
2020-02-14 14:30:08 +08:00
// clear content before mounting
2024-08-07 16:07:47 +08:00
if ( container . nodeType === 1 ) {
container . textContent = ''
}
2023-12-08 18:25:01 +08:00
const proxy = mount ( container , false , resolveRootNamespace ( container ) )
2020-12-05 05:51:38 +08:00
if ( container instanceof Element ) {
container . removeAttribute ( 'v-cloak' )
container . setAttribute ( 'data-v-app' , '' )
}
2020-04-01 06:13:59 +08:00
return proxy
2020-02-14 14:30:08 +08:00
}
return app
} ) as CreateAppFunction < Element >
export const createSSRApp = ( ( . . . args ) = > {
const app = ensureHydrationRenderer ( ) . createApp ( . . . args )
if ( __DEV__ ) {
injectNativeTagCheck ( app )
2021-04-26 23:46:29 +08:00
injectCompilerOptionsCheck ( app )
2020-02-14 14:30:08 +08:00
}
const { mount } = app
2020-12-05 05:51:38 +08:00
app . mount = ( containerOrSelector : Element | ShadowRoot | string ) : any = > {
2020-02-14 14:30:08 +08:00
const container = normalizeContainer ( containerOrSelector )
if ( container ) {
2023-12-08 18:25:01 +08:00
return mount ( container , true , resolveRootNamespace ( container ) )
2020-02-14 12:31:03 +08:00
}
2020-01-17 01:23:47 +08:00
}
2019-10-15 03:36:30 +08:00
return app
2020-02-14 14:30:08 +08:00
} ) as CreateAppFunction < Element >
2024-08-07 16:07:47 +08:00
function resolveRootNamespace (
container : Element | ShadowRoot ,
) : ElementNamespace {
2023-12-08 18:25:01 +08:00
if ( container instanceof SVGElement ) {
return 'svg'
}
if (
typeof MathMLElement === 'function' &&
container instanceof MathMLElement
) {
return 'mathml'
}
}
2020-02-14 14:30:08 +08:00
function injectNativeTagCheck ( app : App ) {
// Inject `isNativeTag`
// this is used for component name validation (dev only)
Object . defineProperty ( app . config , 'isNativeTag' , {
2023-12-08 18:25:01 +08:00
value : ( tag : string ) = > isHTMLTag ( tag ) || isSVGTag ( tag ) || isMathMLTag ( tag ) ,
2020-02-14 14:30:08 +08:00
writable : false ,
} )
}
2021-02-25 05:18:55 +08:00
// dev only
2021-04-26 23:46:29 +08:00
function injectCompilerOptionsCheck ( app : App ) {
2021-02-25 05:18:55 +08:00
if ( isRuntimeOnly ( ) ) {
2021-04-26 23:46:29 +08:00
const isCustomElement = app . config . isCustomElement
2021-02-25 05:18:55 +08:00
Object . defineProperty ( app . config , 'isCustomElement' , {
get ( ) {
2021-04-26 23:46:29 +08:00
return isCustomElement
2021-02-25 05:18:55 +08:00
} ,
set ( ) {
warn (
2021-04-26 23:46:29 +08:00
` The \` isCustomElement \` config option is deprecated. Use ` +
` \` compilerOptions.isCustomElement \` instead. ` ,
2021-02-25 05:18:55 +08:00
)
} ,
} )
2021-04-26 23:46:29 +08:00
const compilerOptions = app . config . compilerOptions
const msg =
` The \` compilerOptions \` config option is only respected when using ` +
` a build of Vue.js that includes the runtime compiler (aka "full build"). ` +
` Since you are using the runtime-only build, \` compilerOptions \` ` +
` must be passed to \` @vue/compiler-dom \` in the build setup instead. \ n ` +
` - For vue-loader: pass it via vue-loader's \` compilerOptions \` loader option. \ n ` +
` - For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader \ n ` +
2023-05-08 14:47:02 +08:00
` - For vite: pass it via @vitejs/plugin-vue options. See https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#example-for-passing-options-to-vuecompiler-sfc `
2021-04-26 23:46:29 +08:00
Object . defineProperty ( app . config , 'compilerOptions' , {
get ( ) {
warn ( msg )
return compilerOptions
} ,
set ( ) {
warn ( msg )
} ,
} )
2021-02-25 05:18:55 +08:00
}
}
2020-12-05 05:51:38 +08:00
function normalizeContainer (
container : Element | ShadowRoot | string ,
2024-08-07 16:07:47 +08:00
) : Element | ShadowRoot | null {
2020-02-14 14:30:08 +08:00
if ( isString ( container ) ) {
const res = document . querySelector ( container )
if ( __DEV__ && ! res ) {
2020-12-05 07:25:13 +08:00
warn (
` Failed to mount app: mount target selector " ${ container } " returned null. ` ,
)
2020-02-14 14:30:08 +08:00
}
return res
}
2020-12-05 05:51:38 +08:00
if (
__DEV__ &&
2021-08-02 21:41:41 +08:00
window . ShadowRoot &&
2021-02-04 02:10:27 +08:00
container instanceof window . ShadowRoot &&
2020-12-05 05:51:38 +08:00
container . mode === 'closed'
) {
warn (
` mounting on a ShadowRoot with \` {mode: "closed"} \` may lead to unpredictable bugs ` ,
)
}
return container as any
2019-10-15 03:36:30 +08:00
}
2021-07-13 03:32:38 +08:00
// Custom element support
export {
defineCustomElement ,
defineSSRCustomElement ,
2024-08-03 14:19:19 +08:00
useShadowRoot ,
2024-08-08 12:35:00 +08:00
useHost ,
2021-07-23 06:19:54 +08:00
VueElement ,
2023-02-02 16:20:32 +08:00
type VueElementConstructor ,
2024-08-06 15:37:28 +08:00
type CustomElementOptions ,
2021-07-13 03:32:38 +08:00
} from './apiCustomElement'
2020-07-10 04:25:29 +08:00
// SFC CSS utilities
2020-07-13 06:04:09 +08:00
export { useCssModule } from './helpers/useCssModule'
export { useCssVars } from './helpers/useCssVars'
2020-07-10 04:25:29 +08:00
2020-05-01 05:04:35 +08:00
// DOM-only components
2023-02-02 16:20:32 +08:00
export { Transition , type TransitionProps } from './components/Transition'
2020-05-01 05:04:35 +08:00
export {
TransitionGroup ,
2023-02-02 16:20:32 +08:00
type TransitionGroupProps ,
2020-05-01 05:04:35 +08:00
} from './components/TransitionGroup'
// **Internal** DOM-only runtime directive helpers
2019-10-11 06:02:51 +08:00
export {
vModelText ,
vModelCheckbox ,
vModelRadio ,
vModelSelect ,
vModelDynamic ,
} from './directives/vModel'
2019-10-19 04:20:45 +08:00
export { withModifiers , withKeys } from './directives/vOn'
2019-11-29 07:41:01 +08:00
export { vShow } from './directives/vShow'
2019-10-14 12:33:23 +08:00
2021-09-24 03:02:19 +08:00
import { initVModelForSSR } from './directives/vModel'
import { initVShowForSSR } from './directives/vShow'
let ssrDirectiveInitialized = false
/ * *
* @internal
* /
2024-08-13 22:02:57 +08:00
export const initDirectivesForSSR : ( ) = > void = __SSR__
2021-09-24 03:02:19 +08:00
? ( ) = > {
if ( ! ssrDirectiveInitialized ) {
ssrDirectiveInitialized = true
initVModelForSSR ( )
initVShowForSSR ( )
}
}
: NOOP
2018-09-20 09:51:21 +08:00
// re-export everything from core
2019-08-20 21:58:10 +08:00
// h, Component, reactivity API, nextTick, flags & types
2018-10-27 03:44:50 +08:00
export * from '@vue/runtime-core'
2023-03-29 20:22:29 +08:00
export * from './jsx'