2023-07-24 03:13:08 +00:00
function makeMap ( str , expectsLowerCase ) {
2023-09-06 01:51:55 +00:00
const map = /* @__PURE__ */ Object . create ( null ) ;
const list = str . split ( "," ) ;
for ( let i = 0 ; i < list . length ; i ++ ) {
map [ list [ i ] ] = true ;
}
return expectsLowerCase ? ( val ) => ! ! map [ val . toLowerCase ( ) ] : ( val ) => ! ! map [ val ] ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
const EMPTY _OBJ = Object . freeze ( { } ) ;
const NOOP = ( ) => {
} ;
const NO = ( ) => false ;
const onRE = /^on[^a-z]/ ;
const isOn = ( key ) => onRE . test ( key ) ;
const extend = Object . assign ;
const isArray = Array . isArray ;
const isString = ( val ) => typeof val === "string" ;
const isSymbol = ( val ) => typeof val === "symbol" ;
const isObject = ( val ) => val !== null && typeof val === "object" ;
const isReservedProp = /* @__PURE__ */ makeMap (
// the leading comma is intentional so empty string "" is also included
",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"
) ;
const isBuiltInDirective = /* @__PURE__ */ makeMap (
"bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo"
) ;
const cacheStringFunction = ( fn ) => {
const cache = /* @__PURE__ */ Object . create ( null ) ;
return ( str ) => {
const hit = cache [ str ] ;
return hit || ( cache [ str ] = fn ( str ) ) ;
} ;
} ;
const camelizeRE = /-(\w)/g ;
const camelize = cacheStringFunction ( ( str ) => {
return str . replace ( camelizeRE , ( _ , c ) => c ? c . toUpperCase ( ) : "" ) ;
} ) ;
const hyphenateRE = /\B([A-Z])/g ;
const hyphenate = cacheStringFunction (
( str ) => str . replace ( hyphenateRE , "-$1" ) . toLowerCase ( )
) ;
const capitalize = cacheStringFunction (
( str ) => str . charAt ( 0 ) . toUpperCase ( ) + str . slice ( 1 )
) ;
const toHandlerKey = cacheStringFunction (
( str ) => str ? ` on ${ capitalize ( str ) } ` : ` `
) ;
2023-07-24 03:13:08 +00:00
const PatchFlagNames = {
2023-09-06 01:51:55 +00:00
[ 1 ] : ` TEXT ` ,
[ 2 ] : ` CLASS ` ,
[ 4 ] : ` STYLE ` ,
[ 8 ] : ` PROPS ` ,
[ 16 ] : ` FULL_PROPS ` ,
[ 32 ] : ` HYDRATE_EVENTS ` ,
[ 64 ] : ` STABLE_FRAGMENT ` ,
[ 128 ] : ` KEYED_FRAGMENT ` ,
[ 256 ] : ` UNKEYED_FRAGMENT ` ,
[ 512 ] : ` NEED_PATCH ` ,
[ 1024 ] : ` DYNAMIC_SLOTS ` ,
[ 2048 ] : ` DEV_ROOT_FRAGMENT ` ,
[ - 1 ] : ` HOISTED ` ,
[ - 2 ] : ` BAIL `
2023-07-24 03:13:08 +00:00
} ;
const slotFlagsText = {
2023-09-06 01:51:55 +00:00
[ 1 ] : "STABLE" ,
[ 2 ] : "DYNAMIC" ,
[ 3 ] : "FORWARDED"
2023-07-24 03:13:08 +00:00
} ;
const range = 2 ;
function generateCodeFrame ( source , start = 0 , end = source . length ) {
2023-09-06 01:51:55 +00:00
let lines = source . split ( /(\r?\n)/ ) ;
const newlineSequences = lines . filter ( ( _ , idx ) => idx % 2 === 1 ) ;
lines = lines . filter ( ( _ , idx ) => idx % 2 === 0 ) ;
let count = 0 ;
const res = [ ] ;
for ( let i = 0 ; i < lines . length ; i ++ ) {
count += lines [ i ] . length + ( newlineSequences [ i ] && newlineSequences [ i ] . length || 0 ) ;
if ( count >= start ) {
for ( let j = i - range ; j <= i + range || end > count ; j ++ ) {
if ( j < 0 || j >= lines . length )
continue ;
const line = j + 1 ;
res . push (
` ${ line } ${ " " . repeat ( Math . max ( 3 - String ( line ) . length , 0 ) ) } | ${ lines [ j ] } `
) ;
const lineLength = lines [ j ] . length ;
const newLineSeqLength = newlineSequences [ j ] && newlineSequences [ j ] . length || 0 ;
if ( j === i ) {
const pad = start - ( count - ( lineLength + newLineSeqLength ) ) ;
const length = Math . max (
1 ,
end > count ? lineLength - pad : end - start
) ;
res . push ( ` | ` + " " . repeat ( pad ) + "^" . repeat ( length ) ) ;
} else if ( j > i ) {
if ( end > count ) {
const length = Math . max ( Math . min ( end - count , lineLength ) , 1 ) ;
res . push ( ` | ` + "^" . repeat ( length ) ) ;
}
count += lineLength + newLineSeqLength ;
}
}
break ;
}
}
return res . join ( "\n" ) ;
2023-07-24 03:13:08 +00:00
}
const listDelimiterRE = /;(?![^(]*\))/g ;
const propertyDelimiterRE = /:([^]+)/ ;
2023-09-06 01:51:55 +00:00
const styleCommentRE = /\/\*[^]*?\*\//g ;
2023-07-24 03:13:08 +00:00
function parseStringStyle ( cssText ) {
2023-09-06 01:51:55 +00:00
const ret = { } ;
cssText . replace ( styleCommentRE , "" ) . split ( listDelimiterRE ) . forEach ( ( item ) => {
if ( item ) {
const tmp = item . split ( propertyDelimiterRE ) ;
tmp . length > 1 && ( ret [ tmp [ 0 ] . trim ( ) ] = tmp [ 1 ] . trim ( ) ) ;
}
} ) ;
return ret ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
const HTML _TAGS = "html,body,base,head,link,meta,style,title,address,article,aside,footer,header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot" ;
const SVG _TAGS = "svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistantLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,text,textPath,title,tspan,unknown,use,view" ;
const VOID _TAGS = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr" ;
const isHTMLTag = /* @__PURE__ */ makeMap ( HTML _TAGS ) ;
const isSVGTag = /* @__PURE__ */ makeMap ( SVG _TAGS ) ;
const isVoidTag = /* @__PURE__ */ makeMap ( VOID _TAGS ) ;
2023-07-24 03:13:08 +00:00
function defaultOnError ( error ) {
2023-09-06 01:51:55 +00:00
throw error ;
2023-07-24 03:13:08 +00:00
}
function defaultOnWarn ( msg ) {
2023-09-06 01:51:55 +00:00
console . warn ( ` [Vue warn] ${ msg . message } ` ) ;
2023-07-24 03:13:08 +00:00
}
function createCompilerError ( code , loc , messages , additionalMessage ) {
2023-09-06 01:51:55 +00:00
const msg = ( messages || errorMessages ) [ code ] + ( additionalMessage || ` ` ) ;
const error = new SyntaxError ( String ( msg ) ) ;
error . code = code ;
error . loc = loc ;
return error ;
2023-07-24 03:13:08 +00:00
}
const errorMessages = {
2023-09-06 01:51:55 +00:00
// parse errors
[ 0 ] : "Illegal comment." ,
[ 1 ] : "CDATA section is allowed only in XML context." ,
[ 2 ] : "Duplicate attribute." ,
[ 3 ] : "End tag cannot have attributes." ,
[ 4 ] : "Illegal '/' in tags." ,
[ 5 ] : "Unexpected EOF in tag." ,
[ 6 ] : "Unexpected EOF in CDATA section." ,
[ 7 ] : "Unexpected EOF in comment." ,
[ 8 ] : "Unexpected EOF in script." ,
[ 9 ] : "Unexpected EOF in tag." ,
[ 10 ] : "Incorrectly closed comment." ,
[ 11 ] : "Incorrectly opened comment." ,
[ 12 ] : "Illegal tag name. Use '<' to print '<'." ,
[ 13 ] : "Attribute value was expected." ,
[ 14 ] : "End tag name was expected." ,
[ 15 ] : "Whitespace was expected." ,
[ 16 ] : "Unexpected '<!--' in comment." ,
[ 17 ] : ` Attribute name cannot contain U+0022 ("), U+0027 ('), and U+003C (<). ` ,
[ 18 ] : "Unquoted attribute value cannot contain U+0022 (\"), U+0027 ('), U+003C (<), U+003D (=), and U+0060 (`)." ,
[ 19 ] : "Attribute name cannot start with '='." ,
[ 21 ] : "'<?' is allowed only in XML context." ,
[ 20 ] : ` Unexpected null character. ` ,
[ 22 ] : "Illegal '/' in tags." ,
// Vue-specific parse errors
[ 23 ] : "Invalid end tag." ,
[ 24 ] : "Element is missing end tag." ,
[ 25 ] : "Interpolation end sign was not found." ,
[ 27 ] : "End bracket for dynamic directive argument was not found. Note that dynamic directive argument cannot contain spaces." ,
[ 26 ] : "Legal directive name was expected." ,
// transform errors
[ 28 ] : ` v-if/v-else-if is missing expression. ` ,
[ 29 ] : ` v-if/else branches must use unique keys. ` ,
[ 30 ] : ` v-else/v-else-if has no adjacent v-if or v-else-if. ` ,
[ 31 ] : ` v-for is missing expression. ` ,
[ 32 ] : ` v-for has invalid expression. ` ,
[ 33 ] : ` <template v-for> key should be placed on the <template> tag. ` ,
[ 34 ] : ` v-bind is missing expression. ` ,
[ 35 ] : ` v-on is missing expression. ` ,
[ 36 ] : ` Unexpected custom directive on <slot> outlet. ` ,
[ 37 ] : ` Mixed v-slot usage on both the component and nested <template>. When there are multiple named slots, all slots should use <template> syntax to avoid scope ambiguity. ` ,
[ 38 ] : ` Duplicate slot names found. ` ,
[ 39 ] : ` Extraneous children found when component already has explicitly named default slot. These children will be ignored. ` ,
[ 40 ] : ` v-slot can only be used on components or <template> tags. ` ,
[ 41 ] : ` v-model is missing expression. ` ,
[ 42 ] : ` v-model value must be a valid JavaScript member expression. ` ,
[ 43 ] : ` v-model cannot be used on v-for or v-slot scope variables because they are not writable. ` ,
[ 44 ] : ` v-model cannot be used on a prop, because local prop bindings are not writable.
Use a v - bind binding combined with a v - on listener that emits update : x event instead . ` ,
[ 45 ] : ` Error parsing JavaScript expression: ` ,
[ 46 ] : ` <KeepAlive> expects exactly one child component. ` ,
// generic errors
[ 47 ] : ` "prefixIdentifiers" option is not supported in this build of compiler. ` ,
[ 48 ] : ` ES module mode is not supported in this build of compiler. ` ,
[ 49 ] : ` "cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled. ` ,
[ 50 ] : ` "scopeId" option is only supported in module mode. ` ,
// deprecations
[ 51 ] : ` @vnode-* hooks in templates are deprecated. Use the vue: prefix instead. For example, @vnode-mounted should be changed to @vue:mounted. @vnode-* hooks support will be removed in 3.4. ` ,
[ 52 ] : ` v-is="component-name" has been deprecated. Use is="vue:component-name" instead. v-is support will be removed in 3.4. ` ,
// just to fulfill types
[ 53 ] : ` `
2023-07-24 03:13:08 +00:00
} ;
const FRAGMENT = Symbol ( ` Fragment ` ) ;
const TELEPORT = Symbol ( ` Teleport ` ) ;
const SUSPENSE = Symbol ( ` Suspense ` ) ;
const KEEP _ALIVE = Symbol ( ` KeepAlive ` ) ;
const BASE _TRANSITION = Symbol ( ` BaseTransition ` ) ;
const OPEN _BLOCK = Symbol ( ` openBlock ` ) ;
const CREATE _BLOCK = Symbol ( ` createBlock ` ) ;
const CREATE _ELEMENT _BLOCK = Symbol ( ` createElementBlock ` ) ;
const CREATE _VNODE = Symbol ( ` createVNode ` ) ;
const CREATE _ELEMENT _VNODE = Symbol ( ` createElementVNode ` ) ;
const CREATE _COMMENT = Symbol ( ` createCommentVNode ` ) ;
const CREATE _TEXT = Symbol ( ` createTextVNode ` ) ;
const CREATE _STATIC = Symbol ( ` createStaticVNode ` ) ;
const RESOLVE _COMPONENT = Symbol ( ` resolveComponent ` ) ;
2023-09-06 01:51:55 +00:00
const RESOLVE _DYNAMIC _COMPONENT = Symbol (
` resolveDynamicComponent `
) ;
2023-07-24 03:13:08 +00:00
const RESOLVE _DIRECTIVE = Symbol ( ` resolveDirective ` ) ;
const RESOLVE _FILTER = Symbol ( ` resolveFilter ` ) ;
const WITH _DIRECTIVES = Symbol ( ` withDirectives ` ) ;
const RENDER _LIST = Symbol ( ` renderList ` ) ;
const RENDER _SLOT = Symbol ( ` renderSlot ` ) ;
const CREATE _SLOTS = Symbol ( ` createSlots ` ) ;
const TO _DISPLAY _STRING = Symbol ( ` toDisplayString ` ) ;
const MERGE _PROPS = Symbol ( ` mergeProps ` ) ;
const NORMALIZE _CLASS = Symbol ( ` normalizeClass ` ) ;
const NORMALIZE _STYLE = Symbol ( ` normalizeStyle ` ) ;
const NORMALIZE _PROPS = Symbol ( ` normalizeProps ` ) ;
const GUARD _REACTIVE _PROPS = Symbol ( ` guardReactiveProps ` ) ;
const TO _HANDLERS = Symbol ( ` toHandlers ` ) ;
const CAMELIZE = Symbol ( ` camelize ` ) ;
const CAPITALIZE = Symbol ( ` capitalize ` ) ;
const TO _HANDLER _KEY = Symbol ( ` toHandlerKey ` ) ;
const SET _BLOCK _TRACKING = Symbol ( ` setBlockTracking ` ) ;
const PUSH _SCOPE _ID = Symbol ( ` pushScopeId ` ) ;
const POP _SCOPE _ID = Symbol ( ` popScopeId ` ) ;
const WITH _CTX = Symbol ( ` withCtx ` ) ;
const UNREF = Symbol ( ` unref ` ) ;
const IS _REF = Symbol ( ` isRef ` ) ;
const WITH _MEMO = Symbol ( ` withMemo ` ) ;
const IS _MEMO _SAME = Symbol ( ` isMemoSame ` ) ;
const helperNameMap = {
2023-09-06 01:51:55 +00:00
[ FRAGMENT ] : ` Fragment ` ,
[ TELEPORT ] : ` Teleport ` ,
[ SUSPENSE ] : ` Suspense ` ,
[ KEEP _ALIVE ] : ` KeepAlive ` ,
[ BASE _TRANSITION ] : ` BaseTransition ` ,
[ OPEN _BLOCK ] : ` openBlock ` ,
[ CREATE _BLOCK ] : ` createBlock ` ,
[ CREATE _ELEMENT _BLOCK ] : ` createElementBlock ` ,
[ CREATE _VNODE ] : ` createVNode ` ,
[ CREATE _ELEMENT _VNODE ] : ` createElementVNode ` ,
[ CREATE _COMMENT ] : ` createCommentVNode ` ,
[ CREATE _TEXT ] : ` createTextVNode ` ,
[ CREATE _STATIC ] : ` createStaticVNode ` ,
[ RESOLVE _COMPONENT ] : ` resolveComponent ` ,
[ RESOLVE _DYNAMIC _COMPONENT ] : ` resolveDynamicComponent ` ,
[ RESOLVE _DIRECTIVE ] : ` resolveDirective ` ,
[ RESOLVE _FILTER ] : ` resolveFilter ` ,
[ WITH _DIRECTIVES ] : ` withDirectives ` ,
[ RENDER _LIST ] : ` renderList ` ,
[ RENDER _SLOT ] : ` renderSlot ` ,
[ CREATE _SLOTS ] : ` createSlots ` ,
[ TO _DISPLAY _STRING ] : ` toDisplayString ` ,
[ MERGE _PROPS ] : ` mergeProps ` ,
[ NORMALIZE _CLASS ] : ` normalizeClass ` ,
[ NORMALIZE _STYLE ] : ` normalizeStyle ` ,
[ NORMALIZE _PROPS ] : ` normalizeProps ` ,
[ GUARD _REACTIVE _PROPS ] : ` guardReactiveProps ` ,
[ TO _HANDLERS ] : ` toHandlers ` ,
[ CAMELIZE ] : ` camelize ` ,
[ CAPITALIZE ] : ` capitalize ` ,
[ TO _HANDLER _KEY ] : ` toHandlerKey ` ,
[ SET _BLOCK _TRACKING ] : ` setBlockTracking ` ,
[ PUSH _SCOPE _ID ] : ` pushScopeId ` ,
[ POP _SCOPE _ID ] : ` popScopeId ` ,
[ WITH _CTX ] : ` withCtx ` ,
[ UNREF ] : ` unref ` ,
[ IS _REF ] : ` isRef ` ,
[ WITH _MEMO ] : ` withMemo ` ,
[ IS _MEMO _SAME ] : ` isMemoSame `
2023-07-24 03:13:08 +00:00
} ;
function registerRuntimeHelpers ( helpers ) {
2023-09-06 01:51:55 +00:00
Object . getOwnPropertySymbols ( helpers ) . forEach ( ( s ) => {
helperNameMap [ s ] = helpers [ s ] ;
} ) ;
2023-07-24 03:13:08 +00:00
}
const locStub = {
2023-09-06 01:51:55 +00:00
source : "" ,
start : { line : 1 , column : 1 , offset : 0 } ,
end : { line : 1 , column : 1 , offset : 0 }
2023-07-24 03:13:08 +00:00
} ;
function createRoot ( children , loc = locStub ) {
2023-09-06 01:51:55 +00:00
return {
type : 0 ,
children ,
helpers : /* @__PURE__ */ new Set ( ) ,
components : [ ] ,
directives : [ ] ,
hoists : [ ] ,
imports : [ ] ,
cached : 0 ,
temps : 0 ,
codegenNode : void 0 ,
loc
} ;
2023-07-24 03:13:08 +00:00
}
function createVNodeCall ( context , tag , props , children , patchFlag , dynamicProps , directives , isBlock = false , disableTracking = false , isComponent = false , loc = locStub ) {
2023-09-06 01:51:55 +00:00
if ( context ) {
if ( isBlock ) {
context . helper ( OPEN _BLOCK ) ;
context . helper ( getVNodeBlockHelper ( context . inSSR , isComponent ) ) ;
} else {
context . helper ( getVNodeHelper ( context . inSSR , isComponent ) ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
if ( directives ) {
context . helper ( WITH _DIRECTIVES ) ;
}
}
return {
type : 13 ,
tag ,
props ,
children ,
patchFlag ,
dynamicProps ,
directives ,
isBlock ,
disableTracking ,
isComponent ,
loc
} ;
2023-07-24 03:13:08 +00:00
}
function createArrayExpression ( elements , loc = locStub ) {
2023-09-06 01:51:55 +00:00
return {
type : 17 ,
loc ,
elements
} ;
2023-07-24 03:13:08 +00:00
}
function createObjectExpression ( properties , loc = locStub ) {
2023-09-06 01:51:55 +00:00
return {
type : 15 ,
loc ,
properties
} ;
2023-07-24 03:13:08 +00:00
}
function createObjectProperty ( key , value ) {
2023-09-06 01:51:55 +00:00
return {
type : 16 ,
loc : locStub ,
key : isString ( key ) ? createSimpleExpression ( key , true ) : key ,
value
} ;
}
function createSimpleExpression ( content , isStatic = false , loc = locStub , constType = 0 ) {
return {
type : 4 ,
loc ,
content ,
isStatic ,
constType : isStatic ? 3 : constType
} ;
2023-07-24 03:13:08 +00:00
}
function createInterpolation ( content , loc ) {
2023-09-06 01:51:55 +00:00
return {
type : 5 ,
loc ,
content : isString ( content ) ? createSimpleExpression ( content , false , loc ) : content
} ;
2023-07-24 03:13:08 +00:00
}
function createCompoundExpression ( children , loc = locStub ) {
2023-09-06 01:51:55 +00:00
return {
type : 8 ,
loc ,
children
} ;
2023-07-24 03:13:08 +00:00
}
function createCallExpression ( callee , args = [ ] , loc = locStub ) {
2023-09-06 01:51:55 +00:00
return {
type : 14 ,
loc ,
callee ,
arguments : args
} ;
}
function createFunctionExpression ( params , returns = void 0 , newline = false , isSlot = false , loc = locStub ) {
return {
type : 18 ,
params ,
returns ,
newline ,
isSlot ,
loc
} ;
2023-07-24 03:13:08 +00:00
}
function createConditionalExpression ( test , consequent , alternate , newline = true ) {
2023-09-06 01:51:55 +00:00
return {
type : 19 ,
test ,
consequent ,
alternate ,
newline ,
loc : locStub
} ;
2023-07-24 03:13:08 +00:00
}
function createCacheExpression ( index , value , isVNode = false ) {
2023-09-06 01:51:55 +00:00
return {
type : 20 ,
index ,
value ,
isVNode ,
loc : locStub
} ;
2023-07-24 03:13:08 +00:00
}
function createBlockStatement ( body ) {
2023-09-06 01:51:55 +00:00
return {
type : 21 ,
body ,
loc : locStub
} ;
2023-07-24 03:13:08 +00:00
}
function createTemplateLiteral ( elements ) {
2023-09-06 01:51:55 +00:00
return {
type : 22 ,
elements ,
loc : locStub
} ;
2023-07-24 03:13:08 +00:00
}
function createIfStatement ( test , consequent , alternate ) {
2023-09-06 01:51:55 +00:00
return {
type : 23 ,
test ,
consequent ,
alternate ,
loc : locStub
} ;
2023-07-24 03:13:08 +00:00
}
function createAssignmentExpression ( left , right ) {
2023-09-06 01:51:55 +00:00
return {
type : 24 ,
left ,
right ,
loc : locStub
} ;
2023-07-24 03:13:08 +00:00
}
function createSequenceExpression ( expressions ) {
2023-09-06 01:51:55 +00:00
return {
type : 25 ,
expressions ,
loc : locStub
} ;
2023-07-24 03:13:08 +00:00
}
function createReturnStatement ( returns ) {
2023-09-06 01:51:55 +00:00
return {
type : 26 ,
returns ,
loc : locStub
} ;
}
function getVNodeHelper ( ssr , isComponent ) {
return ssr || isComponent ? CREATE _VNODE : CREATE _ELEMENT _VNODE ;
}
function getVNodeBlockHelper ( ssr , isComponent ) {
return ssr || isComponent ? CREATE _BLOCK : CREATE _ELEMENT _BLOCK ;
}
function convertToBlock ( node , { helper , removeHelper , inSSR } ) {
if ( ! node . isBlock ) {
node . isBlock = true ;
removeHelper ( getVNodeHelper ( inSSR , node . isComponent ) ) ;
helper ( OPEN _BLOCK ) ;
helper ( getVNodeBlockHelper ( inSSR , node . isComponent ) ) ;
}
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
const isStaticExp = ( p ) => p . type === 4 && p . isStatic ;
2023-07-24 03:13:08 +00:00
const isBuiltInType = ( tag , expected ) => tag === expected || tag === hyphenate ( expected ) ;
function isCoreComponent ( tag ) {
2023-09-06 01:51:55 +00:00
if ( isBuiltInType ( tag , "Teleport" ) ) {
return TELEPORT ;
} else if ( isBuiltInType ( tag , "Suspense" ) ) {
return SUSPENSE ;
} else if ( isBuiltInType ( tag , "KeepAlive" ) ) {
return KEEP _ALIVE ;
} else if ( isBuiltInType ( tag , "BaseTransition" ) ) {
return BASE _TRANSITION ;
}
2023-07-24 03:13:08 +00:00
}
const nonIdentifierRE = /^\d|[^\$\w]/ ;
const isSimpleIdentifier = ( name ) => ! nonIdentifierRE . test ( name ) ;
const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/ ;
const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/ ;
const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g ;
const isMemberExpressionBrowser = ( path ) => {
2023-09-06 01:51:55 +00:00
path = path . trim ( ) . replace ( whitespaceRE , ( s ) => s . trim ( ) ) ;
let state = 0 /* inMemberExp */ ;
let stateStack = [ ] ;
let currentOpenBracketCount = 0 ;
let currentOpenParensCount = 0 ;
let currentStringType = null ;
for ( let i = 0 ; i < path . length ; i ++ ) {
const char = path . charAt ( i ) ;
switch ( state ) {
case 0 /* inMemberExp */ :
if ( char === "[" ) {
stateStack . push ( state ) ;
state = 1 /* inBrackets */ ;
currentOpenBracketCount ++ ;
} else if ( char === "(" ) {
stateStack . push ( state ) ;
state = 2 /* inParens */ ;
currentOpenParensCount ++ ;
} else if ( ! ( i === 0 ? validFirstIdentCharRE : validIdentCharRE ) . test ( char ) ) {
return false ;
}
break ;
case 1 /* inBrackets */ :
if ( char === ` ' ` || char === ` " ` || char === "`" ) {
stateStack . push ( state ) ;
state = 3 /* inString */ ;
currentStringType = char ;
} else if ( char === ` [ ` ) {
currentOpenBracketCount ++ ;
} else if ( char === ` ] ` ) {
if ( ! -- currentOpenBracketCount ) {
state = stateStack . pop ( ) ;
}
}
break ;
case 2 /* inParens */ :
if ( char === ` ' ` || char === ` " ` || char === "`" ) {
stateStack . push ( state ) ;
state = 3 /* inString */ ;
currentStringType = char ;
} else if ( char === ` ( ` ) {
currentOpenParensCount ++ ;
} else if ( char === ` ) ` ) {
if ( i === path . length - 1 ) {
return false ;
}
if ( ! -- currentOpenParensCount ) {
state = stateStack . pop ( ) ;
}
}
break ;
case 3 /* inString */ :
if ( char === currentStringType ) {
state = stateStack . pop ( ) ;
currentStringType = null ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
break ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
return ! currentOpenBracketCount && ! currentOpenParensCount ;
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
const isMemberExpressionNode = NOOP ;
const isMemberExpression = isMemberExpressionBrowser ;
2023-07-24 03:13:08 +00:00
function getInnerRange ( loc , offset , length ) {
2023-09-06 01:51:55 +00:00
const source = loc . source . slice ( offset , offset + length ) ;
const newLoc = {
source ,
start : advancePositionWithClone ( loc . start , loc . source , offset ) ,
end : loc . end
} ;
if ( length != null ) {
newLoc . end = advancePositionWithClone (
loc . start ,
loc . source ,
offset + length
) ;
}
return newLoc ;
2023-07-24 03:13:08 +00:00
}
function advancePositionWithClone ( pos , source , numberOfCharacters = source . length ) {
2023-09-06 01:51:55 +00:00
return advancePositionWithMutation (
extend ( { } , pos ) ,
source ,
numberOfCharacters
) ;
2023-07-24 03:13:08 +00:00
}
function advancePositionWithMutation ( pos , source , numberOfCharacters = source . length ) {
2023-09-06 01:51:55 +00:00
let linesCount = 0 ;
let lastNewLinePos = - 1 ;
for ( let i = 0 ; i < numberOfCharacters ; i ++ ) {
if ( source . charCodeAt ( i ) === 10 ) {
linesCount ++ ;
lastNewLinePos = i ;
}
}
pos . offset += numberOfCharacters ;
pos . line += linesCount ;
pos . column = lastNewLinePos === - 1 ? pos . column + numberOfCharacters : numberOfCharacters - lastNewLinePos ;
return pos ;
2023-07-24 03:13:08 +00:00
}
function assert ( condition , msg ) {
2023-09-06 01:51:55 +00:00
if ( ! condition ) {
throw new Error ( msg || ` unexpected compiler condition ` ) ;
}
2023-07-24 03:13:08 +00:00
}
function findDir ( node , name , allowEmpty = false ) {
2023-09-06 01:51:55 +00:00
for ( let i = 0 ; i < node . props . length ; i ++ ) {
const p = node . props [ i ] ;
if ( p . type === 7 && ( allowEmpty || p . exp ) && ( isString ( name ) ? p . name === name : name . test ( p . name ) ) ) {
return p ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
2023-07-24 03:13:08 +00:00
}
function findProp ( node , name , dynamicOnly = false , allowEmpty = false ) {
2023-09-06 01:51:55 +00:00
for ( let i = 0 ; i < node . props . length ; i ++ ) {
const p = node . props [ i ] ;
if ( p . type === 6 ) {
if ( dynamicOnly )
continue ;
if ( p . name === name && ( p . value || allowEmpty ) ) {
return p ;
}
} else if ( p . name === "bind" && ( p . exp || allowEmpty ) && isStaticArgOf ( p . arg , name ) ) {
return p ;
}
}
2023-07-24 03:13:08 +00:00
}
function isStaticArgOf ( arg , name ) {
2023-09-06 01:51:55 +00:00
return ! ! ( arg && isStaticExp ( arg ) && arg . content === name ) ;
2023-07-24 03:13:08 +00:00
}
function hasDynamicKeyVBind ( node ) {
2023-09-06 01:51:55 +00:00
return node . props . some (
( p ) => p . type === 7 && p . name === "bind" && ( ! p . arg || // v-bind="obj"
p . arg . type !== 4 || // v-bind:[_ctx.foo]
! p . arg . isStatic )
// v-bind:[foo]
) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
function isText$1 ( node ) {
return node . type === 5 || node . type === 2 ;
2023-07-24 03:13:08 +00:00
}
function isVSlot ( p ) {
2023-09-06 01:51:55 +00:00
return p . type === 7 && p . name === "slot" ;
2023-07-24 03:13:08 +00:00
}
function isTemplateNode ( node ) {
2023-09-06 01:51:55 +00:00
return node . type === 1 && node . tagType === 3 ;
2023-07-24 03:13:08 +00:00
}
function isSlotOutlet ( node ) {
2023-09-06 01:51:55 +00:00
return node . type === 1 && node . tagType === 2 ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
const propsHelperSet = /* @__PURE__ */ new Set ( [ NORMALIZE _PROPS , GUARD _REACTIVE _PROPS ] ) ;
2023-07-24 03:13:08 +00:00
function getUnnormalizedProps ( props , callPath = [ ] ) {
2023-09-06 01:51:55 +00:00
if ( props && ! isString ( props ) && props . type === 14 ) {
const callee = props . callee ;
if ( ! isString ( callee ) && propsHelperSet . has ( callee ) ) {
return getUnnormalizedProps (
props . arguments [ 0 ] ,
callPath . concat ( props )
) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
return [ props , callPath ] ;
2023-07-24 03:13:08 +00:00
}
function injectProp ( node , prop , context ) {
2023-09-06 01:51:55 +00:00
let propsWithInjection ;
let props = node . type === 13 ? node . props : node . arguments [ 2 ] ;
let callPath = [ ] ;
let parentCall ;
if ( props && ! isString ( props ) && props . type === 14 ) {
const ret = getUnnormalizedProps ( props ) ;
props = ret [ 0 ] ;
callPath = ret [ 1 ] ;
parentCall = callPath [ callPath . length - 1 ] ;
}
if ( props == null || isString ( props ) ) {
propsWithInjection = createObjectExpression ( [ prop ] ) ;
} else if ( props . type === 14 ) {
const first = props . arguments [ 0 ] ;
if ( ! isString ( first ) && first . type === 15 ) {
if ( ! hasProp ( prop , first ) ) {
first . properties . unshift ( prop ) ;
}
} else {
if ( props . callee === TO _HANDLERS ) {
2023-07-24 03:13:08 +00:00
propsWithInjection = createCallExpression ( context . helper ( MERGE _PROPS ) , [
2023-09-06 01:51:55 +00:00
createObjectExpression ( [ prop ] ) ,
props
2023-07-24 03:13:08 +00:00
] ) ;
2023-09-06 01:51:55 +00:00
} else {
props . arguments . unshift ( createObjectExpression ( [ prop ] ) ) ;
}
}
! propsWithInjection && ( propsWithInjection = props ) ;
} else if ( props . type === 15 ) {
if ( ! hasProp ( prop , props ) ) {
props . properties . unshift ( prop ) ;
}
propsWithInjection = props ;
} else {
propsWithInjection = createCallExpression ( context . helper ( MERGE _PROPS ) , [
createObjectExpression ( [ prop ] ) ,
props
] ) ;
if ( parentCall && parentCall . callee === GUARD _REACTIVE _PROPS ) {
parentCall = callPath [ callPath . length - 2 ] ;
}
}
if ( node . type === 13 ) {
if ( parentCall ) {
parentCall . arguments [ 0 ] = propsWithInjection ;
} else {
node . props = propsWithInjection ;
}
} else {
if ( parentCall ) {
parentCall . arguments [ 0 ] = propsWithInjection ;
} else {
node . arguments [ 2 ] = propsWithInjection ;
}
}
2023-07-24 03:13:08 +00:00
}
function hasProp ( prop , props ) {
2023-09-06 01:51:55 +00:00
let result = false ;
if ( prop . key . type === 4 ) {
const propKeyName = prop . key . content ;
result = props . properties . some (
( p ) => p . key . type === 4 && p . key . content === propKeyName
) ;
}
return result ;
2023-07-24 03:13:08 +00:00
}
function toValidAssetId ( name , type ) {
2023-09-06 01:51:55 +00:00
return ` _ ${ type } _ ${ name . replace ( /[^\w]/g , ( searchValue , replaceValue ) => {
return searchValue === "-" ? "_" : name . charCodeAt ( replaceValue ) . toString ( ) ;
} ) } ` ;
2023-07-24 03:13:08 +00:00
}
function hasScopeRef ( node , ids ) {
2023-09-06 01:51:55 +00:00
if ( ! node || Object . keys ( ids ) . length === 0 ) {
return false ;
}
switch ( node . type ) {
case 1 :
for ( let i = 0 ; i < node . props . length ; i ++ ) {
const p = node . props [ i ] ;
if ( p . type === 7 && ( hasScopeRef ( p . arg , ids ) || hasScopeRef ( p . exp , ids ) ) ) {
return true ;
}
}
return node . children . some ( ( c ) => hasScopeRef ( c , ids ) ) ;
case 11 :
if ( hasScopeRef ( node . source , ids ) ) {
return true ;
}
return node . children . some ( ( c ) => hasScopeRef ( c , ids ) ) ;
case 9 :
return node . branches . some ( ( b ) => hasScopeRef ( b , ids ) ) ;
case 10 :
if ( hasScopeRef ( node . condition , ids ) ) {
return true ;
}
return node . children . some ( ( c ) => hasScopeRef ( c , ids ) ) ;
case 4 :
return ! node . isStatic && isSimpleIdentifier ( node . content ) && ! ! ids [ node . content ] ;
case 8 :
return node . children . some ( ( c ) => isObject ( c ) && hasScopeRef ( c , ids ) ) ;
case 5 :
case 12 :
return hasScopeRef ( node . content , ids ) ;
case 2 :
case 3 :
return false ;
default :
return false ;
}
2023-07-24 03:13:08 +00:00
}
function getMemoedVNodeCall ( node ) {
2023-09-06 01:51:55 +00:00
if ( node . type === 14 && node . callee === WITH _MEMO ) {
return node . arguments [ 1 ] . returns ;
} else {
return node ;
}
2023-07-24 03:13:08 +00:00
}
const deprecationData = {
2023-09-06 01:51:55 +00:00
[ "COMPILER_IS_ON_ELEMENT" ] : {
message : ` Platform-native elements with "is" prop will no longer be treated as components in Vue 3 unless the "is" value is explicitly prefixed with "vue:". ` ,
link : ` https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html `
} ,
[ "COMPILER_V_BIND_SYNC" ] : {
message : ( key ) => ` .sync modifier for v-bind has been removed. Use v-model with argument instead. \` v-bind: ${ key } .sync \` should be changed to \` v-model: ${ key } \` . ` ,
link : ` https://v3-migration.vuejs.org/breaking-changes/v-model.html `
} ,
[ "COMPILER_V_BIND_PROP" ] : {
message : ` .prop modifier for v-bind has been removed and no longer necessary. Vue 3 will automatically set a binding as DOM property when appropriate. `
} ,
[ "COMPILER_V_BIND_OBJECT_ORDER" ] : {
message : ` v-bind="obj" usage is now order sensitive and behaves like JavaScript object spread: it will now overwrite an existing non-mergeable attribute that appears before v-bind in the case of conflict. To retain 2.x behavior, move v-bind to make it the first attribute. You can also suppress this warning if the usage is intended. ` ,
link : ` https://v3-migration.vuejs.org/breaking-changes/v-bind.html `
} ,
[ "COMPILER_V_ON_NATIVE" ] : {
message : ` .native modifier for v-on has been removed as is no longer necessary. ` ,
link : ` https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html `
} ,
[ "COMPILER_V_IF_V_FOR_PRECEDENCE" ] : {
message : ` v-if / v-for precedence when used on the same element has changed in Vue 3: v-if now takes higher precedence and will no longer have access to v-for scope variables. It is best to avoid the ambiguity with <template> tags or use a computed property that filters v-for data source. ` ,
link : ` https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html `
} ,
[ "COMPILER_NATIVE_TEMPLATE" ] : {
message : ` <template> with no special directives will render as a native template element instead of its inner content in Vue 3. `
} ,
[ "COMPILER_INLINE_TEMPLATE" ] : {
message : ` "inline-template" has been removed in Vue 3. ` ,
link : ` https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html `
} ,
[ "COMPILER_FILTER" ] : {
message : ` filters have been removed in Vue 3. The "|" symbol will be treated as native JavaScript bitwise OR operator. Use method calls or computed properties instead. ` ,
link : ` https://v3-migration.vuejs.org/breaking-changes/filters.html `
}
2023-07-24 03:13:08 +00:00
} ;
function getCompatValue ( key , context ) {
2023-09-06 01:51:55 +00:00
const config = context . options ? context . options . compatConfig : context . compatConfig ;
const value = config && config [ key ] ;
if ( key === "MODE" ) {
return value || 3 ;
} else {
return value ;
}
2023-07-24 03:13:08 +00:00
}
function isCompatEnabled ( key , context ) {
2023-09-06 01:51:55 +00:00
const mode = getCompatValue ( "MODE" , context ) ;
const value = getCompatValue ( key , context ) ;
return mode === 3 ? value === true : value !== false ;
2023-07-24 03:13:08 +00:00
}
function checkCompatEnabled ( key , context , loc , ... args ) {
2023-09-06 01:51:55 +00:00
const enabled = isCompatEnabled ( key , context ) ;
if ( enabled ) {
warnDeprecation ( key , context , loc , ... args ) ;
}
return enabled ;
2023-07-24 03:13:08 +00:00
}
function warnDeprecation ( key , context , loc , ... args ) {
2023-09-06 01:51:55 +00:00
const val = getCompatValue ( key , context ) ;
if ( val === "suppress-warning" ) {
return ;
}
const { message , link } = deprecationData [ key ] ;
const msg = ` (deprecation ${ key } ) ${ typeof message === "function" ? message ( ... args ) : message } ${ link ? `
Details : $ { link } ` : ` ` } ` ;
const err = new SyntaxError ( msg ) ;
err . code = key ;
if ( loc )
err . loc = loc ;
context . onWarn ( err ) ;
2023-07-24 03:13:08 +00:00
}
const decodeRE = /&(gt|lt|amp|apos|quot);/g ;
const decodeMap = {
2023-09-06 01:51:55 +00:00
gt : ">" ,
lt : "<" ,
amp : "&" ,
apos : "'" ,
quot : '"'
2023-07-24 03:13:08 +00:00
} ;
const defaultParserOptions = {
2023-09-06 01:51:55 +00:00
delimiters : [ ` {{ ` , ` }} ` ] ,
getNamespace : ( ) => 0 ,
getTextMode : ( ) => 0 ,
isVoidTag : NO ,
isPreTag : NO ,
isCustomElement : NO ,
decodeEntities : ( rawText ) => rawText . replace ( decodeRE , ( _ , p1 ) => decodeMap [ p1 ] ) ,
onError : defaultOnError ,
onWarn : defaultOnWarn ,
comments : true
2023-07-24 03:13:08 +00:00
} ;
function baseParse ( content , options = { } ) {
2023-09-06 01:51:55 +00:00
const context = createParserContext ( content , options ) ;
const start = getCursor ( context ) ;
return createRoot (
parseChildren ( context , 0 , [ ] ) ,
getSelection ( context , start )
) ;
2023-07-24 03:13:08 +00:00
}
function createParserContext ( content , rawOptions ) {
2023-09-06 01:51:55 +00:00
const options = extend ( { } , defaultParserOptions ) ;
let key ;
for ( key in rawOptions ) {
options [ key ] = rawOptions [ key ] === void 0 ? defaultParserOptions [ key ] : rawOptions [ key ] ;
}
return {
options ,
column : 1 ,
line : 1 ,
offset : 0 ,
originalSource : content ,
source : content ,
inPre : false ,
inVPre : false ,
onWarn : options . onWarn
} ;
2023-07-24 03:13:08 +00:00
}
function parseChildren ( context , mode , ancestors ) {
2023-09-06 01:51:55 +00:00
const parent = last ( ancestors ) ;
const ns = parent ? parent . ns : 0 ;
const nodes = [ ] ;
while ( ! isEnd ( context , mode , ancestors ) ) {
const s = context . source ;
let node = void 0 ;
if ( mode === 0 || mode === 1 ) {
if ( ! context . inVPre && startsWith ( s , context . options . delimiters [ 0 ] ) ) {
node = parseInterpolation ( context , mode ) ;
} else if ( mode === 0 && s [ 0 ] === "<" ) {
if ( s . length === 1 ) {
emitError ( context , 5 , 1 ) ;
} else if ( s [ 1 ] === "!" ) {
if ( startsWith ( s , "<!--" ) ) {
node = parseComment ( context ) ;
} else if ( startsWith ( s , "<!DOCTYPE" ) ) {
node = parseBogusComment ( context ) ;
} else if ( startsWith ( s , "<![CDATA[" ) ) {
if ( ns !== 0 ) {
node = parseCDATA ( context , ancestors ) ;
} else {
emitError ( context , 1 ) ;
node = parseBogusComment ( context ) ;
}
} else {
emitError ( context , 11 ) ;
node = parseBogusComment ( context ) ;
}
} else if ( s [ 1 ] === "/" ) {
if ( s . length === 2 ) {
emitError ( context , 5 , 2 ) ;
} else if ( s [ 2 ] === ">" ) {
emitError ( context , 14 , 2 ) ;
advanceBy ( context , 3 ) ;
continue ;
} else if ( /[a-z]/i . test ( s [ 2 ] ) ) {
emitError ( context , 23 ) ;
parseTag ( context , TagType . End , parent ) ;
continue ;
} else {
emitError (
context ,
12 ,
2
) ;
node = parseBogusComment ( context ) ;
}
} else if ( /[a-z]/i . test ( s [ 1 ] ) ) {
node = parseElement ( context , ancestors ) ;
if ( isCompatEnabled (
"COMPILER_NATIVE_TEMPLATE" ,
context
) && node && node . tag === "template" && ! node . props . some (
( p ) => p . type === 7 && isSpecialTemplateDirective ( p . name )
) ) {
warnDeprecation (
"COMPILER_NATIVE_TEMPLATE" ,
context ,
node . loc
) ;
node = node . children ;
}
} else if ( s [ 1 ] === "?" ) {
emitError (
context ,
21 ,
1
) ;
node = parseBogusComment ( context ) ;
} else {
emitError ( context , 12 , 1 ) ;
}
}
}
if ( ! node ) {
node = parseText ( context , mode ) ;
}
if ( isArray ( node ) ) {
for ( let i = 0 ; i < node . length ; i ++ ) {
pushNode ( nodes , node [ i ] ) ;
}
} else {
pushNode ( nodes , node ) ;
}
}
let removedWhitespace = false ;
if ( mode !== 2 && mode !== 1 ) {
const shouldCondense = context . options . whitespace !== "preserve" ;
for ( let i = 0 ; i < nodes . length ; i ++ ) {
const node = nodes [ i ] ;
if ( node . type === 2 ) {
if ( ! context . inPre ) {
if ( ! /[^\t\r\n\f ]/ . test ( node . content ) ) {
const prev = nodes [ i - 1 ] ;
const next = nodes [ i + 1 ] ;
if ( ! prev || ! next || shouldCondense && ( prev . type === 3 && next . type === 3 || prev . type === 3 && next . type === 1 || prev . type === 1 && next . type === 3 || prev . type === 1 && next . type === 1 && /[\r\n]/ . test ( node . content ) ) ) {
removedWhitespace = true ;
nodes [ i ] = null ;
} else {
node . content = " " ;
}
} else if ( shouldCondense ) {
node . content = node . content . replace ( /[\t\r\n\f ]+/g , " " ) ;
}
} else {
node . content = node . content . replace ( /\r\n/g , "\n" ) ;
}
} else if ( node . type === 3 && ! context . options . comments ) {
removedWhitespace = true ;
nodes [ i ] = null ;
}
}
if ( context . inPre && parent && context . options . isPreTag ( parent . tag ) ) {
const first = nodes [ 0 ] ;
if ( first && first . type === 2 ) {
first . content = first . content . replace ( /^\r?\n/ , "" ) ;
}
}
}
return removedWhitespace ? nodes . filter ( Boolean ) : nodes ;
2023-07-24 03:13:08 +00:00
}
function pushNode ( nodes , node ) {
2023-09-06 01:51:55 +00:00
if ( node . type === 2 ) {
const prev = last ( nodes ) ;
if ( prev && prev . type === 2 && prev . loc . end . offset === node . loc . start . offset ) {
prev . content += node . content ;
prev . loc . end = node . loc . end ;
prev . loc . source += node . loc . source ;
return ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
nodes . push ( node ) ;
2023-07-24 03:13:08 +00:00
}
function parseCDATA ( context , ancestors ) {
2023-09-06 01:51:55 +00:00
advanceBy ( context , 9 ) ;
const nodes = parseChildren ( context , 3 , ancestors ) ;
if ( context . source . length === 0 ) {
emitError ( context , 6 ) ;
} else {
advanceBy ( context , 3 ) ;
}
return nodes ;
2023-07-24 03:13:08 +00:00
}
function parseComment ( context ) {
2023-09-06 01:51:55 +00:00
const start = getCursor ( context ) ;
let content ;
const match = /--(\!)?>/ . exec ( context . source ) ;
if ( ! match ) {
content = context . source . slice ( 4 ) ;
advanceBy ( context , context . source . length ) ;
emitError ( context , 7 ) ;
} else {
if ( match . index <= 3 ) {
emitError ( context , 0 ) ;
}
if ( match [ 1 ] ) {
emitError ( context , 10 ) ;
}
content = context . source . slice ( 4 , match . index ) ;
const s = context . source . slice ( 0 , match . index ) ;
let prevIndex = 1 , nestedIndex = 0 ;
while ( ( nestedIndex = s . indexOf ( "<!--" , prevIndex ) ) !== - 1 ) {
advanceBy ( context , nestedIndex - prevIndex + 1 ) ;
if ( nestedIndex + 4 < s . length ) {
emitError ( context , 16 ) ;
}
prevIndex = nestedIndex + 1 ;
}
advanceBy ( context , match . index + match [ 0 ] . length - prevIndex + 1 ) ;
}
return {
type : 3 ,
content ,
loc : getSelection ( context , start )
} ;
2023-07-24 03:13:08 +00:00
}
function parseBogusComment ( context ) {
2023-09-06 01:51:55 +00:00
const start = getCursor ( context ) ;
const contentStart = context . source [ 1 ] === "?" ? 1 : 2 ;
let content ;
const closeIndex = context . source . indexOf ( ">" ) ;
if ( closeIndex === - 1 ) {
content = context . source . slice ( contentStart ) ;
advanceBy ( context , context . source . length ) ;
} else {
content = context . source . slice ( contentStart , closeIndex ) ;
advanceBy ( context , closeIndex + 1 ) ;
}
return {
type : 3 ,
content ,
loc : getSelection ( context , start )
} ;
2023-07-24 03:13:08 +00:00
}
function parseElement ( context , ancestors ) {
2023-09-06 01:51:55 +00:00
const wasInPre = context . inPre ;
const wasInVPre = context . inVPre ;
const parent = last ( ancestors ) ;
const element = parseTag ( context , TagType . Start , parent ) ;
const isPreBoundary = context . inPre && ! wasInPre ;
const isVPreBoundary = context . inVPre && ! wasInVPre ;
if ( element . isSelfClosing || context . options . isVoidTag ( element . tag ) ) {
2023-07-24 03:13:08 +00:00
if ( isPreBoundary ) {
2023-09-06 01:51:55 +00:00
context . inPre = false ;
2023-07-24 03:13:08 +00:00
}
if ( isVPreBoundary ) {
2023-09-06 01:51:55 +00:00
context . inVPre = false ;
2023-07-24 03:13:08 +00:00
}
return element ;
2023-09-06 01:51:55 +00:00
}
ancestors . push ( element ) ;
const mode = context . options . getTextMode ( element , parent ) ;
const children = parseChildren ( context , mode , ancestors ) ;
ancestors . pop ( ) ;
{
const inlineTemplateProp = element . props . find (
( p ) => p . type === 6 && p . name === "inline-template"
) ;
if ( inlineTemplateProp && checkCompatEnabled (
"COMPILER_INLINE_TEMPLATE" ,
context ,
inlineTemplateProp . loc
) ) {
const loc = getSelection ( context , element . loc . end ) ;
inlineTemplateProp . value = {
type : 2 ,
content : loc . source ,
loc
} ;
}
}
element . children = children ;
if ( startsWithEndTagOpen ( context . source , element . tag ) ) {
parseTag ( context , TagType . End , parent ) ;
} else {
emitError ( context , 24 , 0 , element . loc . start ) ;
if ( context . source . length === 0 && element . tag . toLowerCase ( ) === "script" ) {
const first = children [ 0 ] ;
if ( first && startsWith ( first . loc . source , "<!--" ) ) {
emitError ( context , 8 ) ;
}
}
}
element . loc = getSelection ( context , element . loc . start ) ;
if ( isPreBoundary ) {
context . inPre = false ;
}
if ( isVPreBoundary ) {
context . inVPre = false ;
}
return element ;
}
var TagType = /* @__PURE__ */ ( ( TagType2 ) => {
TagType2 [ TagType2 [ "Start" ] = 0 ] = "Start" ;
TagType2 [ TagType2 [ "End" ] = 1 ] = "End" ;
return TagType2 ;
} ) ( TagType || { } ) ;
const isSpecialTemplateDirective = /* @__PURE__ */ makeMap (
` if,else,else-if,for,slot `
) ;
2023-07-24 03:13:08 +00:00
function parseTag ( context , type , parent ) {
2023-09-06 01:51:55 +00:00
const start = getCursor ( context ) ;
const match = /^<\/?([a-z][^\t\r\n\f />]*)/i . exec ( context . source ) ;
const tag = match [ 1 ] ;
const ns = context . options . getNamespace ( tag , parent ) ;
advanceBy ( context , match [ 0 ] . length ) ;
advanceSpaces ( context ) ;
const cursor = getCursor ( context ) ;
const currentSource = context . source ;
if ( context . options . isPreTag ( tag ) ) {
context . inPre = true ;
}
let props = parseAttributes ( context , type ) ;
if ( type === 0 /* Start */ && ! context . inVPre && props . some ( ( p ) => p . type === 7 && p . name === "pre" ) ) {
context . inVPre = true ;
extend ( context , cursor ) ;
context . source = currentSource ;
props = parseAttributes ( context , type ) . filter ( ( p ) => p . name !== "v-pre" ) ;
}
let isSelfClosing = false ;
if ( context . source . length === 0 ) {
emitError ( context , 9 ) ;
} else {
isSelfClosing = startsWith ( context . source , "/>" ) ;
if ( type === 1 /* End */ && isSelfClosing ) {
emitError ( context , 4 ) ;
}
advanceBy ( context , isSelfClosing ? 2 : 1 ) ;
}
if ( type === 1 /* End */ ) {
return ;
}
if ( isCompatEnabled (
"COMPILER_V_IF_V_FOR_PRECEDENCE" ,
context
) ) {
let hasIf = false ;
let hasFor = false ;
for ( let i = 0 ; i < props . length ; i ++ ) {
const p = props [ i ] ;
if ( p . type === 7 ) {
if ( p . name === "if" ) {
hasIf = true ;
} else if ( p . name === "for" ) {
hasFor = true ;
}
}
if ( hasIf && hasFor ) {
warnDeprecation (
"COMPILER_V_IF_V_FOR_PRECEDENCE" ,
context ,
getSelection ( context , start )
) ;
break ;
}
}
}
let tagType = 0 ;
if ( ! context . inVPre ) {
if ( tag === "slot" ) {
tagType = 2 ;
} else if ( tag === "template" ) {
if ( props . some (
( p ) => p . type === 7 && isSpecialTemplateDirective ( p . name )
) ) {
tagType = 3 ;
}
} else if ( isComponent ( tag , props , context ) ) {
tagType = 1 ;
}
}
return {
type : 1 ,
ns ,
tag ,
tagType ,
props ,
isSelfClosing ,
children : [ ] ,
loc : getSelection ( context , start ) ,
codegenNode : void 0
// to be created during transform phase
} ;
2023-07-24 03:13:08 +00:00
}
function isComponent ( tag , props , context ) {
2023-09-06 01:51:55 +00:00
const options = context . options ;
if ( options . isCustomElement ( tag ) ) {
return false ;
}
if ( tag === "component" || /^[A-Z]/ . test ( tag ) || isCoreComponent ( tag ) || options . isBuiltInComponent && options . isBuiltInComponent ( tag ) || options . isNativeTag && ! options . isNativeTag ( tag ) ) {
return true ;
}
for ( let i = 0 ; i < props . length ; i ++ ) {
const p = props [ i ] ;
if ( p . type === 6 ) {
if ( p . name === "is" && p . value ) {
if ( p . value . content . startsWith ( "vue:" ) ) {
return true ;
} else if ( checkCompatEnabled (
"COMPILER_IS_ON_ELEMENT" ,
context ,
p . loc
) ) {
return true ;
}
}
} else {
if ( p . name === "is" ) {
2023-07-24 03:13:08 +00:00
return true ;
2023-09-06 01:51:55 +00:00
} else if (
// :is on plain element - only treat as component in compat mode
p . name === "bind" && isStaticArgOf ( p . arg , "is" ) && true && checkCompatEnabled (
"COMPILER_IS_ON_ELEMENT" ,
context ,
p . loc
)
) {
return true ;
}
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
2023-07-24 03:13:08 +00:00
}
function parseAttributes ( context , type ) {
2023-09-06 01:51:55 +00:00
const props = [ ] ;
const attributeNames = /* @__PURE__ */ new Set ( ) ;
while ( context . source . length > 0 && ! startsWith ( context . source , ">" ) && ! startsWith ( context . source , "/>" ) ) {
if ( startsWith ( context . source , "/" ) ) {
emitError ( context , 22 ) ;
advanceBy ( context , 1 ) ;
advanceSpaces ( context ) ;
continue ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
if ( type === 1 /* End */ ) {
emitError ( context , 3 ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
const attr = parseAttribute ( context , attributeNames ) ;
if ( attr . type === 6 && attr . value && attr . name === "class" ) {
attr . value . content = attr . value . content . replace ( /\s+/g , " " ) . trim ( ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
if ( type === 0 /* Start */ ) {
props . push ( attr ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
if ( /^[^\t\r\n\f />]/ . test ( context . source ) ) {
emitError ( context , 15 ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
advanceSpaces ( context ) ;
}
return props ;
}
function parseAttribute ( context , nameSet ) {
var _a ;
const start = getCursor ( context ) ;
const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/ . exec ( context . source ) ;
const name = match [ 0 ] ;
if ( nameSet . has ( name ) ) {
emitError ( context , 2 ) ;
}
nameSet . add ( name ) ;
if ( name [ 0 ] === "=" ) {
emitError ( context , 19 ) ;
}
{
const pattern = /["'<]/g ;
let m ;
while ( m = pattern . exec ( name ) ) {
emitError (
context ,
17 ,
m . index
) ;
}
}
advanceBy ( context , name . length ) ;
let value = void 0 ;
if ( /^[\t\r\n\f ]*=/ . test ( context . source ) ) {
advanceSpaces ( context ) ;
advanceBy ( context , 1 ) ;
advanceSpaces ( context ) ;
value = parseAttributeValue ( context ) ;
if ( ! value ) {
emitError ( context , 13 ) ;
}
}
const loc = getSelection ( context , start ) ;
if ( ! context . inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/ . test ( name ) ) {
const match2 = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i . exec (
name
) ;
let isPropShorthand = startsWith ( name , "." ) ;
let dirName = match2 [ 1 ] || ( isPropShorthand || startsWith ( name , ":" ) ? "bind" : startsWith ( name , "@" ) ? "on" : "slot" ) ;
let arg ;
if ( match2 [ 2 ] ) {
const isSlot = dirName === "slot" ;
const startOffset = name . lastIndexOf (
match2 [ 2 ] ,
name . length - ( ( ( _a = match2 [ 3 ] ) == null ? void 0 : _a . length ) || 0 )
) ;
const loc2 = getSelection (
context ,
getNewPosition ( context , start , startOffset ) ,
getNewPosition (
context ,
start ,
startOffset + match2 [ 2 ] . length + ( isSlot && match2 [ 3 ] || "" ) . length
)
) ;
let content = match2 [ 2 ] ;
let isStatic = true ;
if ( content . startsWith ( "[" ) ) {
isStatic = false ;
if ( ! content . endsWith ( "]" ) ) {
emitError (
context ,
27
) ;
content = content . slice ( 1 ) ;
} else {
content = content . slice ( 1 , content . length - 1 ) ;
}
} else if ( isSlot ) {
content += match2 [ 3 ] || "" ;
}
arg = {
type : 4 ,
content ,
isStatic ,
constType : isStatic ? 3 : 0 ,
loc : loc2
} ;
}
if ( value && value . isQuoted ) {
const valueLoc = value . loc ;
valueLoc . start . offset ++ ;
valueLoc . start . column ++ ;
valueLoc . end = advancePositionWithClone ( valueLoc . start , value . content ) ;
valueLoc . source = valueLoc . source . slice ( 1 , - 1 ) ;
}
const modifiers = match2 [ 3 ] ? match2 [ 3 ] . slice ( 1 ) . split ( "." ) : [ ] ;
if ( isPropShorthand )
modifiers . push ( "prop" ) ;
if ( dirName === "bind" && arg ) {
if ( modifiers . includes ( "sync" ) && checkCompatEnabled (
"COMPILER_V_BIND_SYNC" ,
context ,
loc ,
arg . loc . source
) ) {
dirName = "model" ;
modifiers . splice ( modifiers . indexOf ( "sync" ) , 1 ) ;
}
if ( modifiers . includes ( "prop" ) ) {
checkCompatEnabled (
"COMPILER_V_BIND_PROP" ,
context ,
loc
) ;
}
2023-07-24 03:13:08 +00:00
}
return {
2023-09-06 01:51:55 +00:00
type : 7 ,
name : dirName ,
exp : value && {
type : 4 ,
content : value . content ,
isStatic : false ,
// Treat as non-constant by default. This can be potentially set to
// other values by `transformExpression` to make it eligible for hoisting.
constType : 0 ,
loc : value . loc
} ,
arg ,
modifiers ,
loc
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
}
if ( ! context . inVPre && startsWith ( name , "v-" ) ) {
emitError ( context , 26 ) ;
}
return {
type : 6 ,
name ,
value : value && {
type : 2 ,
content : value . content ,
loc : value . loc
} ,
loc
} ;
2023-07-24 03:13:08 +00:00
}
function parseAttributeValue ( context ) {
2023-09-06 01:51:55 +00:00
const start = getCursor ( context ) ;
let content ;
const quote = context . source [ 0 ] ;
const isQuoted = quote === ` " ` || quote === ` ' ` ;
if ( isQuoted ) {
advanceBy ( context , 1 ) ;
const endIndex = context . source . indexOf ( quote ) ;
if ( endIndex === - 1 ) {
content = parseTextData (
context ,
context . source . length ,
4
) ;
} else {
content = parseTextData ( context , endIndex , 4 ) ;
advanceBy ( context , 1 ) ;
}
} else {
const match = /^[^\t\r\n\f >]+/ . exec ( context . source ) ;
if ( ! match ) {
return void 0 ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
const unexpectedChars = /["'<=`]/g ;
let m ;
while ( m = unexpectedChars . exec ( match [ 0 ] ) ) {
emitError (
context ,
18 ,
m . index
) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
content = parseTextData ( context , match [ 0 ] . length , 4 ) ;
}
return { content , isQuoted , loc : getSelection ( context , start ) } ;
2023-07-24 03:13:08 +00:00
}
function parseInterpolation ( context , mode ) {
2023-09-06 01:51:55 +00:00
const [ open , close ] = context . options . delimiters ;
const closeIndex = context . source . indexOf ( close , open . length ) ;
if ( closeIndex === - 1 ) {
emitError ( context , 25 ) ;
return void 0 ;
}
const start = getCursor ( context ) ;
advanceBy ( context , open . length ) ;
const innerStart = getCursor ( context ) ;
const innerEnd = getCursor ( context ) ;
const rawContentLength = closeIndex - open . length ;
const rawContent = context . source . slice ( 0 , rawContentLength ) ;
const preTrimContent = parseTextData ( context , rawContentLength , mode ) ;
const content = preTrimContent . trim ( ) ;
const startOffset = preTrimContent . indexOf ( content ) ;
if ( startOffset > 0 ) {
advancePositionWithMutation ( innerStart , rawContent , startOffset ) ;
}
const endOffset = rawContentLength - ( preTrimContent . length - content . length - startOffset ) ;
advancePositionWithMutation ( innerEnd , rawContent , endOffset ) ;
advanceBy ( context , close . length ) ;
return {
type : 5 ,
content : {
type : 4 ,
isStatic : false ,
// Set `isConstant` to false by default and will decide in transformExpression
constType : 0 ,
content ,
loc : getSelection ( context , innerStart , innerEnd )
} ,
loc : getSelection ( context , start )
} ;
2023-07-24 03:13:08 +00:00
}
function parseText ( context , mode ) {
2023-09-06 01:51:55 +00:00
const endTokens = mode === 3 ? [ "]]>" ] : [ "<" , context . options . delimiters [ 0 ] ] ;
let endIndex = context . source . length ;
for ( let i = 0 ; i < endTokens . length ; i ++ ) {
const index = context . source . indexOf ( endTokens [ i ] , 1 ) ;
if ( index !== - 1 && endIndex > index ) {
endIndex = index ;
}
}
const start = getCursor ( context ) ;
const content = parseTextData ( context , endIndex , mode ) ;
return {
type : 2 ,
content ,
loc : getSelection ( context , start )
} ;
2023-07-24 03:13:08 +00:00
}
function parseTextData ( context , length , mode ) {
2023-09-06 01:51:55 +00:00
const rawText = context . source . slice ( 0 , length ) ;
advanceBy ( context , length ) ;
if ( mode === 2 || mode === 3 || ! rawText . includes ( "&" ) ) {
return rawText ;
} else {
return context . options . decodeEntities (
rawText ,
mode === 4
) ;
}
2023-07-24 03:13:08 +00:00
}
function getCursor ( context ) {
2023-09-06 01:51:55 +00:00
const { column , line , offset } = context ;
return { column , line , offset } ;
2023-07-24 03:13:08 +00:00
}
function getSelection ( context , start , end ) {
2023-09-06 01:51:55 +00:00
end = end || getCursor ( context ) ;
return {
start ,
end ,
source : context . originalSource . slice ( start . offset , end . offset )
} ;
2023-07-24 03:13:08 +00:00
}
function last ( xs ) {
2023-09-06 01:51:55 +00:00
return xs [ xs . length - 1 ] ;
2023-07-24 03:13:08 +00:00
}
function startsWith ( source , searchString ) {
2023-09-06 01:51:55 +00:00
return source . startsWith ( searchString ) ;
2023-07-24 03:13:08 +00:00
}
function advanceBy ( context , numberOfCharacters ) {
2023-09-06 01:51:55 +00:00
const { source } = context ;
advancePositionWithMutation ( context , source , numberOfCharacters ) ;
context . source = source . slice ( numberOfCharacters ) ;
2023-07-24 03:13:08 +00:00
}
function advanceSpaces ( context ) {
2023-09-06 01:51:55 +00:00
const match = /^[\t\r\n\f ]+/ . exec ( context . source ) ;
if ( match ) {
advanceBy ( context , match [ 0 ] . length ) ;
}
2023-07-24 03:13:08 +00:00
}
function getNewPosition ( context , start , numberOfCharacters ) {
2023-09-06 01:51:55 +00:00
return advancePositionWithClone (
start ,
context . originalSource . slice ( start . offset , numberOfCharacters ) ,
numberOfCharacters
) ;
2023-07-24 03:13:08 +00:00
}
function emitError ( context , code , offset , loc = getCursor ( context ) ) {
2023-09-06 01:51:55 +00:00
if ( offset ) {
loc . offset += offset ;
loc . column += offset ;
}
context . options . onError (
createCompilerError ( code , {
start : loc ,
end : loc ,
source : ""
} )
) ;
2023-07-24 03:13:08 +00:00
}
function isEnd ( context , mode , ancestors ) {
2023-09-06 01:51:55 +00:00
const s = context . source ;
switch ( mode ) {
case 0 :
if ( startsWith ( s , "</" ) ) {
for ( let i = ancestors . length - 1 ; i >= 0 ; -- i ) {
if ( startsWithEndTagOpen ( s , ancestors [ i ] . tag ) ) {
return true ;
}
}
}
break ;
case 1 :
case 2 : {
const parent = last ( ancestors ) ;
if ( parent && startsWithEndTagOpen ( s , parent . tag ) ) {
return true ;
}
break ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
case 3 :
if ( startsWith ( s , "]]>" ) ) {
return true ;
}
break ;
}
return ! s ;
2023-07-24 03:13:08 +00:00
}
function startsWithEndTagOpen ( source , tag ) {
2023-09-06 01:51:55 +00:00
return startsWith ( source , "</" ) && source . slice ( 2 , 2 + tag . length ) . toLowerCase ( ) === tag . toLowerCase ( ) && /[\t\r\n\f />]/ . test ( source [ 2 + tag . length ] || ">" ) ;
2023-07-24 03:13:08 +00:00
}
function hoistStatic ( root , context ) {
2023-09-06 01:51:55 +00:00
walk (
root ,
context ,
2023-07-24 03:13:08 +00:00
// Root node is unfortunately non-hoistable due to potential parent
// fallthrough attributes.
2023-09-06 01:51:55 +00:00
isSingleElementRoot ( root , root . children [ 0 ] )
) ;
2023-07-24 03:13:08 +00:00
}
function isSingleElementRoot ( root , child ) {
2023-09-06 01:51:55 +00:00
const { children } = root ;
return children . length === 1 && child . type === 1 && ! isSlotOutlet ( child ) ;
2023-07-24 03:13:08 +00:00
}
function walk ( node , context , doNotHoistNode = false ) {
2023-09-06 01:51:55 +00:00
const { children } = node ;
const originalCount = children . length ;
let hoistedCount = 0 ;
for ( let i = 0 ; i < children . length ; i ++ ) {
const child = children [ i ] ;
if ( child . type === 1 && child . tagType === 0 ) {
const constantType = doNotHoistNode ? 0 : getConstantType ( child , context ) ;
if ( constantType > 0 ) {
if ( constantType >= 2 ) {
child . codegenNode . patchFlag = - 1 + ( ` /* HOISTED */ ` ) ;
child . codegenNode = context . hoist ( child . codegenNode ) ;
hoistedCount ++ ;
continue ;
}
} else {
const codegenNode = child . codegenNode ;
if ( codegenNode . type === 13 ) {
const flag = getPatchFlag ( codegenNode ) ;
if ( ( ! flag || flag === 512 || flag === 1 ) && getGeneratedPropsConstantType ( child , context ) >= 2 ) {
const props = getNodeProps ( child ) ;
if ( props ) {
codegenNode . props = context . hoist ( props ) ;
}
}
if ( codegenNode . dynamicProps ) {
codegenNode . dynamicProps = context . hoist ( codegenNode . dynamicProps ) ;
}
}
}
}
if ( child . type === 1 ) {
const isComponent = child . tagType === 1 ;
if ( isComponent ) {
context . scopes . vSlot ++ ;
}
walk ( child , context ) ;
if ( isComponent ) {
context . scopes . vSlot -- ;
}
} else if ( child . type === 11 ) {
walk ( child , context , child . children . length === 1 ) ;
} else if ( child . type === 9 ) {
for ( let i2 = 0 ; i2 < child . branches . length ; i2 ++ ) {
walk (
child . branches [ i2 ] ,
context ,
child . branches [ i2 ] . children . length === 1
) ;
}
}
}
if ( hoistedCount && context . transformHoist ) {
context . transformHoist ( children , context , node ) ;
}
if ( hoistedCount && hoistedCount === originalCount && node . type === 1 && node . tagType === 0 && node . codegenNode && node . codegenNode . type === 13 && isArray ( node . codegenNode . children ) ) {
node . codegenNode . children = context . hoist (
createArrayExpression ( node . codegenNode . children )
) ;
}
2023-07-24 03:13:08 +00:00
}
function getConstantType ( node , context ) {
2023-09-06 01:51:55 +00:00
const { constantCache } = context ;
switch ( node . type ) {
case 1 :
if ( node . tagType !== 0 ) {
return 0 ;
}
const cached = constantCache . get ( node ) ;
if ( cached !== void 0 ) {
return cached ;
}
const codegenNode = node . codegenNode ;
if ( codegenNode . type !== 13 ) {
return 0 ;
}
if ( codegenNode . isBlock && node . tag !== "svg" && node . tag !== "foreignObject" ) {
return 0 ;
}
const flag = getPatchFlag ( codegenNode ) ;
if ( ! flag ) {
let returnType2 = 3 ;
const generatedPropsType = getGeneratedPropsConstantType ( node , context ) ;
if ( generatedPropsType === 0 ) {
constantCache . set ( node , 0 ) ;
return 0 ;
}
if ( generatedPropsType < returnType2 ) {
returnType2 = generatedPropsType ;
}
for ( let i = 0 ; i < node . children . length ; i ++ ) {
const childType = getConstantType ( node . children [ i ] , context ) ;
if ( childType === 0 ) {
constantCache . set ( node , 0 ) ;
return 0 ;
}
if ( childType < returnType2 ) {
returnType2 = childType ;
}
}
if ( returnType2 > 1 ) {
for ( let i = 0 ; i < node . props . length ; i ++ ) {
const p = node . props [ i ] ;
if ( p . type === 7 && p . name === "bind" && p . exp ) {
const expType = getConstantType ( p . exp , context ) ;
if ( expType === 0 ) {
constantCache . set ( node , 0 ) ;
return 0 ;
}
if ( expType < returnType2 ) {
returnType2 = expType ;
}
}
}
}
if ( codegenNode . isBlock ) {
for ( let i = 0 ; i < node . props . length ; i ++ ) {
const p = node . props [ i ] ;
if ( p . type === 7 ) {
constantCache . set ( node , 0 ) ;
return 0 ;
}
}
context . removeHelper ( OPEN _BLOCK ) ;
context . removeHelper (
getVNodeBlockHelper ( context . inSSR , codegenNode . isComponent )
) ;
codegenNode . isBlock = false ;
context . helper ( getVNodeHelper ( context . inSSR , codegenNode . isComponent ) ) ;
}
constantCache . set ( node , returnType2 ) ;
return returnType2 ;
} else {
constantCache . set ( node , 0 ) ;
return 0 ;
}
case 2 :
case 3 :
return 3 ;
case 9 :
case 11 :
case 10 :
return 0 ;
case 5 :
case 12 :
return getConstantType ( node . content , context ) ;
case 4 :
return node . constType ;
case 8 :
let returnType = 3 ;
for ( let i = 0 ; i < node . children . length ; i ++ ) {
const child = node . children [ i ] ;
if ( isString ( child ) || isSymbol ( child ) ) {
continue ;
}
const childType = getConstantType ( child , context ) ;
if ( childType === 0 ) {
return 0 ;
} else if ( childType < returnType ) {
returnType = childType ;
}
}
return returnType ;
default :
return 0 ;
}
}
const allowHoistedHelperSet = /* @__PURE__ */ new Set ( [
NORMALIZE _CLASS ,
NORMALIZE _STYLE ,
NORMALIZE _PROPS ,
GUARD _REACTIVE _PROPS
2023-07-24 03:13:08 +00:00
] ) ;
function getConstantTypeOfHelperCall ( value , context ) {
2023-09-06 01:51:55 +00:00
if ( value . type === 14 && ! isString ( value . callee ) && allowHoistedHelperSet . has ( value . callee ) ) {
const arg = value . arguments [ 0 ] ;
if ( arg . type === 4 ) {
return getConstantType ( arg , context ) ;
} else if ( arg . type === 14 ) {
return getConstantTypeOfHelperCall ( arg , context ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
return 0 ;
2023-07-24 03:13:08 +00:00
}
function getGeneratedPropsConstantType ( node , context ) {
2023-09-06 01:51:55 +00:00
let returnType = 3 ;
const props = getNodeProps ( node ) ;
if ( props && props . type === 15 ) {
const { properties } = props ;
for ( let i = 0 ; i < properties . length ; i ++ ) {
const { key , value } = properties [ i ] ;
const keyType = getConstantType ( key , context ) ;
if ( keyType === 0 ) {
return keyType ;
}
if ( keyType < returnType ) {
returnType = keyType ;
}
let valueType ;
if ( value . type === 4 ) {
valueType = getConstantType ( value , context ) ;
} else if ( value . type === 14 ) {
valueType = getConstantTypeOfHelperCall ( value , context ) ;
} else {
valueType = 0 ;
}
if ( valueType === 0 ) {
return valueType ;
}
if ( valueType < returnType ) {
returnType = valueType ;
}
}
}
return returnType ;
2023-07-24 03:13:08 +00:00
}
function getNodeProps ( node ) {
2023-09-06 01:51:55 +00:00
const codegenNode = node . codegenNode ;
if ( codegenNode . type === 13 ) {
return codegenNode . props ;
}
2023-07-24 03:13:08 +00:00
}
function getPatchFlag ( node ) {
2023-09-06 01:51:55 +00:00
const flag = node . patchFlag ;
return flag ? parseInt ( flag , 10 ) : void 0 ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
function createTransformContext ( root , {
filename = "" ,
prefixIdentifiers = false ,
hoistStatic : hoistStatic2 = false ,
cacheHandlers = false ,
nodeTransforms = [ ] ,
directiveTransforms = { } ,
transformHoist = null ,
isBuiltInComponent = NOOP ,
isCustomElement = NOOP ,
expressionPlugins = [ ] ,
scopeId = null ,
slotted = true ,
ssr = false ,
inSSR = false ,
ssrCssVars = ` ` ,
bindingMetadata = EMPTY _OBJ ,
inline = false ,
isTS = false ,
onError = defaultOnError ,
onWarn = defaultOnWarn ,
compatConfig
} ) {
const nameMatch = filename . replace ( /\?.*$/ , "" ) . match ( /([^/\\]+)\.\w+$/ ) ;
const context = {
// options
selfName : nameMatch && capitalize ( camelize ( nameMatch [ 1 ] ) ) ,
prefixIdentifiers ,
hoistStatic : hoistStatic2 ,
cacheHandlers ,
nodeTransforms ,
directiveTransforms ,
transformHoist ,
isBuiltInComponent ,
isCustomElement ,
expressionPlugins ,
scopeId ,
slotted ,
ssr ,
inSSR ,
ssrCssVars ,
bindingMetadata ,
inline ,
isTS ,
onError ,
onWarn ,
compatConfig ,
// state
root ,
helpers : /* @__PURE__ */ new Map ( ) ,
components : /* @__PURE__ */ new Set ( ) ,
directives : /* @__PURE__ */ new Set ( ) ,
hoists : [ ] ,
imports : [ ] ,
constantCache : /* @__PURE__ */ new Map ( ) ,
temps : 0 ,
cached : 0 ,
identifiers : /* @__PURE__ */ Object . create ( null ) ,
scopes : {
vFor : 0 ,
vSlot : 0 ,
vPre : 0 ,
vOnce : 0
} ,
parent : null ,
currentNode : root ,
childIndex : 0 ,
inVOnce : false ,
// methods
helper ( name ) {
const count = context . helpers . get ( name ) || 0 ;
context . helpers . set ( name , count + 1 ) ;
return name ;
} ,
removeHelper ( name ) {
const count = context . helpers . get ( name ) ;
if ( count ) {
const currentCount = count - 1 ;
if ( ! currentCount ) {
context . helpers . delete ( name ) ;
} else {
context . helpers . set ( name , currentCount ) ;
}
}
} ,
helperString ( name ) {
return ` _ ${ helperNameMap [ context . helper ( name ) ] } ` ;
} ,
replaceNode ( node ) {
{
if ( ! context . currentNode ) {
throw new Error ( ` Node being replaced is already removed. ` ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
if ( ! context . parent ) {
throw new Error ( ` Cannot replace root node. ` ) ;
}
}
context . parent . children [ context . childIndex ] = context . currentNode = node ;
} ,
removeNode ( node ) {
if ( ! context . parent ) {
throw new Error ( ` Cannot remove root node. ` ) ;
}
const list = context . parent . children ;
const removalIndex = node ? list . indexOf ( node ) : context . currentNode ? context . childIndex : - 1 ;
if ( removalIndex < 0 ) {
throw new Error ( ` node being removed is not a child of current parent ` ) ;
}
if ( ! node || node === context . currentNode ) {
context . currentNode = null ;
context . onNodeRemoved ( ) ;
} else {
if ( context . childIndex > removalIndex ) {
context . childIndex -- ;
context . onNodeRemoved ( ) ;
}
}
context . parent . children . splice ( removalIndex , 1 ) ;
} ,
onNodeRemoved : ( ) => {
} ,
addIdentifiers ( exp ) {
} ,
removeIdentifiers ( exp ) {
} ,
hoist ( exp ) {
if ( isString ( exp ) )
exp = createSimpleExpression ( exp ) ;
context . hoists . push ( exp ) ;
const identifier = createSimpleExpression (
` _hoisted_ ${ context . hoists . length } ` ,
false ,
exp . loc ,
2
) ;
identifier . hoisted = exp ;
return identifier ;
} ,
cache ( exp , isVNode = false ) {
return createCacheExpression ( context . cached ++ , exp , isVNode ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
} ;
{
context . filters = /* @__PURE__ */ new Set ( ) ;
}
return context ;
2023-07-24 03:13:08 +00:00
}
function transform ( root , options ) {
2023-09-06 01:51:55 +00:00
const context = createTransformContext ( root , options ) ;
traverseNode ( root , context ) ;
if ( options . hoistStatic ) {
hoistStatic ( root , context ) ;
}
if ( ! options . ssr ) {
createRootCodegen ( root , context ) ;
}
root . helpers = /* @__PURE__ */ new Set ( [ ... context . helpers . keys ( ) ] ) ;
root . components = [ ... context . components ] ;
root . directives = [ ... context . directives ] ;
root . imports = context . imports ;
root . hoists = context . hoists ;
root . temps = context . temps ;
root . cached = context . cached ;
{
root . filters = [ ... context . filters ] ;
}
2023-07-24 03:13:08 +00:00
}
function createRootCodegen ( root , context ) {
2023-09-06 01:51:55 +00:00
const { helper } = context ;
const { children } = root ;
if ( children . length === 1 ) {
const child = children [ 0 ] ;
if ( isSingleElementRoot ( root , child ) && child . codegenNode ) {
const codegenNode = child . codegenNode ;
if ( codegenNode . type === 13 ) {
convertToBlock ( codegenNode , context ) ;
}
root . codegenNode = codegenNode ;
} else {
root . codegenNode = child ;
}
} else if ( children . length > 1 ) {
let patchFlag = 64 ;
let patchFlagText = PatchFlagNames [ 64 ] ;
if ( children . filter ( ( c ) => c . type !== 3 ) . length === 1 ) {
patchFlag |= 2048 ;
patchFlagText += ` , ${ PatchFlagNames [ 2048 ] } ` ;
}
root . codegenNode = createVNodeCall (
context ,
helper ( FRAGMENT ) ,
void 0 ,
root . children ,
patchFlag + ( ` /* ${ patchFlagText } */ ` ) ,
void 0 ,
void 0 ,
true ,
void 0 ,
false
/* isComponent */
) ;
} else ;
2023-07-24 03:13:08 +00:00
}
function traverseChildren ( parent , context ) {
2023-09-06 01:51:55 +00:00
let i = 0 ;
const nodeRemoved = ( ) => {
i -- ;
} ;
for ( ; i < parent . children . length ; i ++ ) {
const child = parent . children [ i ] ;
if ( isString ( child ) )
continue ;
context . parent = parent ;
context . childIndex = i ;
context . onNodeRemoved = nodeRemoved ;
traverseNode ( child , context ) ;
}
2023-07-24 03:13:08 +00:00
}
function traverseNode ( node , context ) {
2023-09-06 01:51:55 +00:00
context . currentNode = node ;
const { nodeTransforms } = context ;
const exitFns = [ ] ;
for ( let i2 = 0 ; i2 < nodeTransforms . length ; i2 ++ ) {
const onExit = nodeTransforms [ i2 ] ( node , context ) ;
if ( onExit ) {
if ( isArray ( onExit ) ) {
exitFns . push ( ... onExit ) ;
} else {
exitFns . push ( onExit ) ;
}
}
if ( ! context . currentNode ) {
return ;
} else {
node = context . currentNode ;
}
}
switch ( node . type ) {
case 3 :
if ( ! context . ssr ) {
context . helper ( CREATE _COMMENT ) ;
}
break ;
case 5 :
if ( ! context . ssr ) {
context . helper ( TO _DISPLAY _STRING ) ;
}
break ;
case 9 :
for ( let i2 = 0 ; i2 < node . branches . length ; i2 ++ ) {
traverseNode ( node . branches [ i2 ] , context ) ;
}
break ;
case 10 :
case 11 :
case 1 :
case 0 :
traverseChildren ( node , context ) ;
break ;
}
context . currentNode = node ;
let i = exitFns . length ;
while ( i -- ) {
exitFns [ i ] ( ) ;
}
2023-07-24 03:13:08 +00:00
}
function createStructuralDirectiveTransform ( name , fn ) {
2023-09-06 01:51:55 +00:00
const matches = isString ( name ) ? ( n ) => n === name : ( n ) => name . test ( n ) ;
return ( node , context ) => {
if ( node . type === 1 ) {
const { props } = node ;
if ( node . tagType === 3 && props . some ( isVSlot ) ) {
return ;
}
const exitFns = [ ] ;
for ( let i = 0 ; i < props . length ; i ++ ) {
const prop = props [ i ] ;
if ( prop . type === 7 && matches ( prop . name ) ) {
props . splice ( i , 1 ) ;
i -- ;
const onExit = fn ( node , prop , context ) ;
if ( onExit )
exitFns . push ( onExit ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
return exitFns ;
}
} ;
2023-07-24 03:13:08 +00:00
}
const PURE _ANNOTATION = ` /*#__PURE__*/ ` ;
const aliasHelper = ( s ) => ` ${ helperNameMap [ s ] } : _ ${ helperNameMap [ s ] } ` ;
2023-09-06 01:51:55 +00:00
function createCodegenContext ( ast , {
mode = "function" ,
prefixIdentifiers = mode === "module" ,
sourceMap = false ,
filename = ` template.vue.html ` ,
scopeId = null ,
optimizeImports = false ,
runtimeGlobalName = ` Vue ` ,
runtimeModuleName = ` vue ` ,
ssrRuntimeModuleName = "vue/server-renderer" ,
ssr = false ,
isTS = false ,
inSSR = false
} ) {
const context = {
mode ,
prefixIdentifiers ,
sourceMap ,
filename ,
scopeId ,
optimizeImports ,
runtimeGlobalName ,
runtimeModuleName ,
ssrRuntimeModuleName ,
ssr ,
isTS ,
inSSR ,
source : ast . loc . source ,
code : ` ` ,
column : 1 ,
line : 1 ,
offset : 0 ,
indentLevel : 0 ,
pure : false ,
map : void 0 ,
helper ( key ) {
return ` _ ${ helperNameMap [ key ] } ` ;
} ,
push ( code , node ) {
context . code += code ;
} ,
indent ( ) {
newline ( ++ context . indentLevel ) ;
} ,
deindent ( withoutNewLine = false ) {
if ( withoutNewLine ) {
-- context . indentLevel ;
} else {
newline ( -- context . indentLevel ) ;
}
} ,
newline ( ) {
newline ( context . indentLevel ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
} ;
function newline ( n ) {
context . push ( "\n" + ` ` . repeat ( n ) ) ;
}
return context ;
2023-07-24 03:13:08 +00:00
}
function generate ( ast , options = { } ) {
2023-09-06 01:51:55 +00:00
const context = createCodegenContext ( ast , options ) ;
if ( options . onContextCreated )
options . onContextCreated ( context ) ;
const {
mode ,
push ,
prefixIdentifiers ,
indent ,
deindent ,
newline ,
scopeId ,
ssr
} = context ;
const helpers = Array . from ( ast . helpers ) ;
const hasHelpers = helpers . length > 0 ;
const useWithBlock = ! prefixIdentifiers && mode !== "module" ;
const isSetupInlined = false ;
const preambleContext = isSetupInlined ? createCodegenContext ( ast , options ) : context ;
{
genFunctionPreamble ( ast , preambleContext ) ;
}
const functionName = ssr ? ` ssrRender ` : ` render ` ;
const args = ssr ? [ "_ctx" , "_push" , "_parent" , "_attrs" ] : [ "_ctx" , "_cache" ] ;
const signature = args . join ( ", " ) ;
{
push ( ` function ${ functionName } ( ${ signature } ) { ` ) ;
}
indent ( ) ;
if ( useWithBlock ) {
push ( ` with (_ctx) { ` ) ;
2023-07-24 03:13:08 +00:00
indent ( ) ;
2023-09-06 01:51:55 +00:00
if ( hasHelpers ) {
push ( ` const { ${ helpers . map ( aliasHelper ) . join ( ", " ) } } = _Vue ` ) ;
push ( `
` );
newline ( ) ;
}
}
if ( ast . components . length ) {
genAssets ( ast . components , "component" , context ) ;
if ( ast . directives . length || ast . temps > 0 ) {
newline ( ) ;
}
}
if ( ast . directives . length ) {
genAssets ( ast . directives , "directive" , context ) ;
2023-07-24 03:13:08 +00:00
if ( ast . temps > 0 ) {
2023-09-06 01:51:55 +00:00
newline ( ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
if ( ast . filters && ast . filters . length ) {
newline ( ) ;
genAssets ( ast . filters , "filter" , context ) ;
newline ( ) ;
}
if ( ast . temps > 0 ) {
push ( ` let ` ) ;
for ( let i = 0 ; i < ast . temps ; i ++ ) {
push ( ` ${ i > 0 ? ` , ` : ` ` } _temp ${ i } ` ) ;
}
}
if ( ast . components . length || ast . directives . length || ast . temps ) {
push ( `
` );
newline ( ) ;
}
if ( ! ssr ) {
push ( ` return ` ) ;
}
if ( ast . codegenNode ) {
genNode ( ast . codegenNode , context ) ;
} else {
push ( ` null ` ) ;
}
if ( useWithBlock ) {
2023-07-24 03:13:08 +00:00
deindent ( ) ;
push ( ` } ` ) ;
2023-09-06 01:51:55 +00:00
}
deindent ( ) ;
push ( ` } ` ) ;
return {
ast ,
code : context . code ,
preamble : isSetupInlined ? preambleContext . code : ` ` ,
// SourceMapGenerator does have toJSON() method but it's not in the types
map : context . map ? context . map . toJSON ( ) : void 0
} ;
2023-07-24 03:13:08 +00:00
}
function genFunctionPreamble ( ast , context ) {
2023-09-06 01:51:55 +00:00
const {
ssr ,
prefixIdentifiers ,
push ,
newline ,
runtimeModuleName ,
runtimeGlobalName ,
ssrRuntimeModuleName
} = context ;
const VueBinding = runtimeGlobalName ;
const helpers = Array . from ( ast . helpers ) ;
if ( helpers . length > 0 ) {
{
push ( ` const _Vue = ${ VueBinding }
` );
if ( ast . hoists . length ) {
const staticHelpers = [
CREATE _VNODE ,
CREATE _ELEMENT _VNODE ,
CREATE _COMMENT ,
CREATE _TEXT ,
CREATE _STATIC
] . filter ( ( helper ) => helpers . includes ( helper ) ) . map ( aliasHelper ) . join ( ", " ) ;
push ( ` const { ${ staticHelpers } } = _Vue
` );
}
}
}
genHoists ( ast . hoists , context ) ;
newline ( ) ;
push ( ` return ` ) ;
2023-07-24 03:13:08 +00:00
}
function genAssets ( assets , type , { helper , push , newline , isTS } ) {
2023-09-06 01:51:55 +00:00
const resolver = helper (
type === "filter" ? RESOLVE _FILTER : type === "component" ? RESOLVE _COMPONENT : RESOLVE _DIRECTIVE
) ;
for ( let i = 0 ; i < assets . length ; i ++ ) {
let id = assets [ i ] ;
const maybeSelfReference = id . endsWith ( "__self" ) ;
if ( maybeSelfReference ) {
id = id . slice ( 0 , - 6 ) ;
}
push (
` const ${ toValidAssetId ( id , type ) } = ${ resolver } ( ${ JSON . stringify ( id ) } ${ maybeSelfReference ? ` , true ` : ` ` } ) ${ isTS ? ` ! ` : ` ` } `
) ;
if ( i < assets . length - 1 ) {
newline ( ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
2023-07-24 03:13:08 +00:00
}
function genHoists ( hoists , context ) {
2023-09-06 01:51:55 +00:00
if ( ! hoists . length ) {
return ;
}
context . pure = true ;
const { push , newline , helper , scopeId , mode } = context ;
newline ( ) ;
for ( let i = 0 ; i < hoists . length ; i ++ ) {
const exp = hoists [ i ] ;
if ( exp ) {
push (
` const _hoisted_ ${ i + 1 } = ${ ` ` } `
) ;
genNode ( exp , context ) ;
newline ( ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
context . pure = false ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
function isText ( n ) {
return isString ( n ) || n . type === 4 || n . type === 2 || n . type === 5 || n . type === 8 ;
2023-07-24 03:13:08 +00:00
}
function genNodeListAsArray ( nodes , context ) {
2023-09-06 01:51:55 +00:00
const multilines = nodes . length > 3 || nodes . some ( ( n ) => isArray ( n ) || ! isText ( n ) ) ;
context . push ( ` [ ` ) ;
multilines && context . indent ( ) ;
genNodeList ( nodes , context , multilines ) ;
multilines && context . deindent ( ) ;
context . push ( ` ] ` ) ;
2023-07-24 03:13:08 +00:00
}
function genNodeList ( nodes , context , multilines = false , comma = true ) {
2023-09-06 01:51:55 +00:00
const { push , newline } = context ;
for ( let i = 0 ; i < nodes . length ; i ++ ) {
const node = nodes [ i ] ;
if ( isString ( node ) ) {
push ( node ) ;
} else if ( isArray ( node ) ) {
genNodeListAsArray ( node , context ) ;
} else {
genNode ( node , context ) ;
}
if ( i < nodes . length - 1 ) {
if ( multilines ) {
comma && push ( "," ) ;
newline ( ) ;
} else {
comma && push ( ", " ) ;
}
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
2023-07-24 03:13:08 +00:00
}
function genNode ( node , context ) {
2023-09-06 01:51:55 +00:00
if ( isString ( node ) ) {
context . push ( node ) ;
return ;
}
if ( isSymbol ( node ) ) {
context . push ( context . helper ( node ) ) ;
return ;
}
switch ( node . type ) {
case 1 :
case 9 :
case 11 :
assert (
node . codegenNode != null ,
` Codegen node is missing for element/if/for node. Apply appropriate transforms first. `
) ;
genNode ( node . codegenNode , context ) ;
break ;
case 2 :
genText ( node , context ) ;
break ;
case 4 :
genExpression ( node , context ) ;
break ;
case 5 :
genInterpolation ( node , context ) ;
break ;
case 12 :
genNode ( node . codegenNode , context ) ;
break ;
case 8 :
genCompoundExpression ( node , context ) ;
break ;
case 3 :
genComment ( node , context ) ;
break ;
case 13 :
genVNodeCall ( node , context ) ;
break ;
case 14 :
genCallExpression ( node , context ) ;
break ;
case 15 :
genObjectExpression ( node , context ) ;
break ;
case 17 :
genArrayExpression ( node , context ) ;
break ;
case 18 :
genFunctionExpression ( node , context ) ;
break ;
case 19 :
genConditionalExpression ( node , context ) ;
break ;
case 20 :
genCacheExpression ( node , context ) ;
break ;
case 21 :
genNodeList ( node . body , context , true , false ) ;
break ;
case 22 :
break ;
case 23 :
break ;
case 24 :
break ;
case 25 :
break ;
case 26 :
break ;
case 10 :
break ;
default :
{
assert ( false , ` unhandled codegen node type: ${ node . type } ` ) ;
const exhaustiveCheck = node ;
return exhaustiveCheck ;
}
}
2023-07-24 03:13:08 +00:00
}
function genText ( node , context ) {
2023-09-06 01:51:55 +00:00
context . push ( JSON . stringify ( node . content ) , node ) ;
2023-07-24 03:13:08 +00:00
}
function genExpression ( node , context ) {
2023-09-06 01:51:55 +00:00
const { content , isStatic } = node ;
context . push ( isStatic ? JSON . stringify ( content ) : content , node ) ;
2023-07-24 03:13:08 +00:00
}
function genInterpolation ( node , context ) {
2023-09-06 01:51:55 +00:00
const { push , helper , pure } = context ;
if ( pure )
push ( PURE _ANNOTATION ) ;
push ( ` ${ helper ( TO _DISPLAY _STRING ) } ( ` ) ;
genNode ( node . content , context ) ;
push ( ` ) ` ) ;
2023-07-24 03:13:08 +00:00
}
function genCompoundExpression ( node , context ) {
2023-09-06 01:51:55 +00:00
for ( let i = 0 ; i < node . children . length ; i ++ ) {
const child = node . children [ i ] ;
if ( isString ( child ) ) {
context . push ( child ) ;
} else {
genNode ( child , context ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
2023-07-24 03:13:08 +00:00
}
function genExpressionAsPropertyKey ( node , context ) {
2023-09-06 01:51:55 +00:00
const { push } = context ;
if ( node . type === 8 ) {
push ( ` [ ` ) ;
genCompoundExpression ( node , context ) ;
push ( ` ] ` ) ;
} else if ( node . isStatic ) {
const text = isSimpleIdentifier ( node . content ) ? node . content : JSON . stringify ( node . content ) ;
push ( text , node ) ;
} else {
push ( ` [ ${ node . content } ] ` , node ) ;
}
2023-07-24 03:13:08 +00:00
}
function genComment ( node , context ) {
2023-09-06 01:51:55 +00:00
const { push , helper , pure } = context ;
if ( pure ) {
push ( PURE _ANNOTATION ) ;
}
push ( ` ${ helper ( CREATE _COMMENT ) } ( ${ JSON . stringify ( node . content ) } ) ` , node ) ;
2023-07-24 03:13:08 +00:00
}
function genVNodeCall ( node , context ) {
2023-09-06 01:51:55 +00:00
const { push , helper , pure } = context ;
const {
tag ,
props ,
children ,
patchFlag ,
dynamicProps ,
directives ,
isBlock ,
disableTracking ,
isComponent
} = node ;
if ( directives ) {
push ( helper ( WITH _DIRECTIVES ) + ` ( ` ) ;
}
if ( isBlock ) {
push ( ` ( ${ helper ( OPEN _BLOCK ) } ( ${ disableTracking ? ` true ` : ` ` } ), ` ) ;
}
if ( pure ) {
push ( PURE _ANNOTATION ) ;
}
const callHelper = isBlock ? getVNodeBlockHelper ( context . inSSR , isComponent ) : getVNodeHelper ( context . inSSR , isComponent ) ;
push ( helper ( callHelper ) + ` ( ` , node ) ;
genNodeList (
genNullableArgs ( [ tag , props , children , patchFlag , dynamicProps ] ) ,
context
) ;
push ( ` ) ` ) ;
if ( isBlock ) {
2023-07-24 03:13:08 +00:00
push ( ` ) ` ) ;
2023-09-06 01:51:55 +00:00
}
if ( directives ) {
push ( ` , ` ) ;
genNode ( directives , context ) ;
push ( ` ) ` ) ;
}
2023-07-24 03:13:08 +00:00
}
function genNullableArgs ( args ) {
2023-09-06 01:51:55 +00:00
let i = args . length ;
while ( i -- ) {
if ( args [ i ] != null )
break ;
}
return args . slice ( 0 , i + 1 ) . map ( ( arg ) => arg || ` null ` ) ;
2023-07-24 03:13:08 +00:00
}
function genCallExpression ( node , context ) {
2023-09-06 01:51:55 +00:00
const { push , helper , pure } = context ;
const callee = isString ( node . callee ) ? node . callee : helper ( node . callee ) ;
if ( pure ) {
push ( PURE _ANNOTATION ) ;
}
push ( callee + ` ( ` , node ) ;
genNodeList ( node . arguments , context ) ;
push ( ` ) ` ) ;
2023-07-24 03:13:08 +00:00
}
function genObjectExpression ( node , context ) {
2023-09-06 01:51:55 +00:00
const { push , indent , deindent , newline } = context ;
const { properties } = node ;
if ( ! properties . length ) {
push ( ` {} ` , node ) ;
return ;
}
const multilines = properties . length > 1 || properties . some ( ( p ) => p . value . type !== 4 ) ;
push ( multilines ? ` { ` : ` { ` ) ;
multilines && indent ( ) ;
for ( let i = 0 ; i < properties . length ; i ++ ) {
const { key , value } = properties [ i ] ;
genExpressionAsPropertyKey ( key , context ) ;
push ( ` : ` ) ;
genNode ( value , context ) ;
if ( i < properties . length - 1 ) {
push ( ` , ` ) ;
newline ( ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
multilines && deindent ( ) ;
push ( multilines ? ` } ` : ` } ` ) ;
2023-07-24 03:13:08 +00:00
}
function genArrayExpression ( node , context ) {
2023-09-06 01:51:55 +00:00
genNodeListAsArray ( node . elements , context ) ;
2023-07-24 03:13:08 +00:00
}
function genFunctionExpression ( node , context ) {
2023-09-06 01:51:55 +00:00
const { push , indent , deindent } = context ;
const { params , returns , body , newline , isSlot } = node ;
if ( isSlot ) {
push ( ` _ ${ helperNameMap [ WITH _CTX ] } ( ` ) ;
}
push ( ` ( ` , node ) ;
if ( isArray ( params ) ) {
genNodeList ( params , context ) ;
} else if ( params ) {
genNode ( params , context ) ;
}
push ( ` ) => ` ) ;
if ( newline || body ) {
push ( ` { ` ) ;
indent ( ) ;
}
if ( returns ) {
if ( newline ) {
push ( ` return ` ) ;
}
if ( isArray ( returns ) ) {
genNodeListAsArray ( returns , context ) ;
} else {
genNode ( returns , context ) ;
}
} else if ( body ) {
genNode ( body , context ) ;
}
if ( newline || body ) {
deindent ( ) ;
push ( ` } ` ) ;
}
if ( isSlot ) {
if ( node . isNonScopedSlot ) {
push ( ` , undefined, true ` ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
push ( ` ) ` ) ;
}
2023-07-24 03:13:08 +00:00
}
function genConditionalExpression ( node , context ) {
2023-09-06 01:51:55 +00:00
const { test , consequent , alternate , newline : needNewline } = node ;
const { push , indent , deindent , newline } = context ;
if ( test . type === 4 ) {
const needsParens = ! isSimpleIdentifier ( test . content ) ;
needsParens && push ( ` ( ` ) ;
genExpression ( test , context ) ;
needsParens && push ( ` ) ` ) ;
} else {
push ( ` ( ` ) ;
genNode ( test , context ) ;
push ( ` ) ` ) ;
}
needNewline && indent ( ) ;
context . indentLevel ++ ;
needNewline || push ( ` ` ) ;
push ( ` ? ` ) ;
genNode ( consequent , context ) ;
context . indentLevel -- ;
needNewline && newline ( ) ;
needNewline || push ( ` ` ) ;
push ( ` : ` ) ;
const isNested = alternate . type === 19 ;
if ( ! isNested ) {
2023-07-24 03:13:08 +00:00
context . indentLevel ++ ;
2023-09-06 01:51:55 +00:00
}
genNode ( alternate , context ) ;
if ( ! isNested ) {
2023-07-24 03:13:08 +00:00
context . indentLevel -- ;
2023-09-06 01:51:55 +00:00
}
needNewline && deindent (
true
/* without newline */
) ;
2023-07-24 03:13:08 +00:00
}
function genCacheExpression ( node , context ) {
2023-09-06 01:51:55 +00:00
const { push , helper , indent , deindent , newline } = context ;
push ( ` _cache[ ${ node . index } ] || ( ` ) ;
if ( node . isVNode ) {
indent ( ) ;
push ( ` ${ helper ( SET _BLOCK _TRACKING ) } (-1), ` ) ;
newline ( ) ;
}
push ( ` _cache[ ${ node . index } ] = ` ) ;
genNode ( node . value , context ) ;
if ( node . isVNode ) {
push ( ` , ` ) ;
newline ( ) ;
push ( ` ${ helper ( SET _BLOCK _TRACKING ) } (1), ` ) ;
newline ( ) ;
push ( ` _cache[ ${ node . index } ] ` ) ;
deindent ( ) ;
}
push ( ` ) ` ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
function walkIdentifiers ( root , onIdentifier , includeAll = false , parentStack = [ ] , knownIds = /* @__PURE__ */ Object . create ( null ) ) {
{
return ;
}
2023-07-24 03:13:08 +00:00
}
function isReferencedIdentifier ( id , parent , parentStack ) {
2023-09-06 01:51:55 +00:00
{
return false ;
}
2023-07-24 03:13:08 +00:00
}
function isInDestructureAssignment ( parent , parentStack ) {
2023-09-06 01:51:55 +00:00
if ( parent && ( parent . type === "ObjectProperty" || parent . type === "ArrayPattern" ) ) {
let i = parentStack . length ;
while ( i -- ) {
const p = parentStack [ i ] ;
if ( p . type === "AssignmentExpression" ) {
return true ;
} else if ( p . type !== "ObjectProperty" && ! p . type . endsWith ( "Pattern" ) ) {
break ;
}
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
return false ;
2023-07-24 03:13:08 +00:00
}
function walkFunctionParams ( node , onIdent ) {
2023-09-06 01:51:55 +00:00
for ( const p of node . params ) {
for ( const id of extractIdentifiers ( p ) ) {
onIdent ( id ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
2023-07-24 03:13:08 +00:00
}
function walkBlockDeclarations ( block , onIdent ) {
2023-09-06 01:51:55 +00:00
for ( const stmt of block . body ) {
if ( stmt . type === "VariableDeclaration" ) {
if ( stmt . declare )
continue ;
for ( const decl of stmt . declarations ) {
for ( const id of extractIdentifiers ( decl . id ) ) {
onIdent ( id ) ;
}
}
} else if ( stmt . type === "FunctionDeclaration" || stmt . type === "ClassDeclaration" ) {
if ( stmt . declare || ! stmt . id )
continue ;
onIdent ( stmt . id ) ;
}
}
2023-07-24 03:13:08 +00:00
}
function extractIdentifiers ( param , nodes = [ ] ) {
2023-09-06 01:51:55 +00:00
switch ( param . type ) {
case "Identifier" :
nodes . push ( param ) ;
break ;
case "MemberExpression" :
let object = param ;
while ( object . type === "MemberExpression" ) {
object = object . object ;
}
nodes . push ( object ) ;
break ;
case "ObjectPattern" :
for ( const prop of param . properties ) {
if ( prop . type === "RestElement" ) {
extractIdentifiers ( prop . argument , nodes ) ;
} else {
extractIdentifiers ( prop . value , nodes ) ;
}
}
break ;
case "ArrayPattern" :
param . elements . forEach ( ( element ) => {
if ( element )
extractIdentifiers ( element , nodes ) ;
} ) ;
break ;
case "RestElement" :
extractIdentifiers ( param . argument , nodes ) ;
break ;
case "AssignmentPattern" :
extractIdentifiers ( param . left , nodes ) ;
break ;
}
return nodes ;
2023-07-24 03:13:08 +00:00
}
const isFunctionType = ( node ) => {
2023-09-06 01:51:55 +00:00
return /Function(?:Expression|Declaration)$|Method$/ . test ( node . type ) ;
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
const isStaticProperty = ( node ) => node && ( node . type === "ObjectProperty" || node . type === "ObjectMethod" ) && ! node . computed ;
2023-07-24 03:13:08 +00:00
const isStaticPropertyKey = ( node , parent ) => isStaticProperty ( parent ) && parent . key === node ;
2023-09-06 01:51:55 +00:00
const TS _NODE _TYPES = [
"TSAsExpression" ,
// foo as number
"TSTypeAssertion" ,
// (<number>foo)
"TSNonNullExpression" ,
// foo!
"TSInstantiationExpression" ,
// foo<string>
"TSSatisfiesExpression"
// foo satisfies T
] ;
2023-07-24 03:13:08 +00:00
2023-09-06 01:51:55 +00:00
const prohibitedKeywordRE = new RegExp (
"\\b" + "arguments,await,break,case,catch,class,const,continue,debugger,default,delete,do,else,export,extends,finally,for,function,if,import,let,new,return,super,switch,throw,try,var,void,while,with,yield" . split ( "," ) . join ( "\\b|\\b" ) + "\\b"
) ;
2023-07-24 03:13:08 +00:00
const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g ;
function validateBrowserExpression ( node , context , asParams = false , asRawStatements = false ) {
2023-09-06 01:51:55 +00:00
const exp = node . content ;
if ( ! exp . trim ( ) ) {
return ;
}
try {
new Function (
asRawStatements ? ` ${ exp } ` : ` return ${ asParams ? ` ( ${ exp } ) => {} ` : ` ( ${ exp } ) ` } `
) ;
} catch ( e ) {
let message = e . message ;
const keywordMatch = exp . replace ( stripStringRE , "" ) . match ( prohibitedKeywordRE ) ;
if ( keywordMatch ) {
message = ` avoid using JavaScript keyword as property name: " ${ keywordMatch [ 0 ] } " ` ;
}
context . onError (
createCompilerError (
45 ,
node . loc ,
void 0 ,
message
)
) ;
}
2023-07-24 03:13:08 +00:00
}
const transformExpression = ( node , context ) => {
2023-09-06 01:51:55 +00:00
if ( node . type === 5 ) {
node . content = processExpression (
node . content ,
context
) ;
} else if ( node . type === 1 ) {
for ( let i = 0 ; i < node . props . length ; i ++ ) {
const dir = node . props [ i ] ;
if ( dir . type === 7 && dir . name !== "for" ) {
const exp = dir . exp ;
const arg = dir . arg ;
if ( exp && exp . type === 4 && ! ( dir . name === "on" && arg ) ) {
dir . exp = processExpression (
exp ,
context ,
// slot args must be processed as function params
dir . name === "slot"
) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
if ( arg && arg . type === 4 && ! arg . isStatic ) {
dir . arg = processExpression ( arg , context ) ;
}
}
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
function processExpression ( node , context , asParams = false , asRawStatements = false , localVars = Object . create ( context . identifiers ) ) {
{
2023-07-24 03:13:08 +00:00
{
2023-09-06 01:51:55 +00:00
validateBrowserExpression ( node , context , asParams , asRawStatements ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
return node ;
}
2023-07-24 03:13:08 +00:00
}
function stringifyExpression ( exp ) {
2023-09-06 01:51:55 +00:00
if ( isString ( exp ) ) {
return exp ;
} else if ( exp . type === 4 ) {
return exp . content ;
} else {
return exp . children . map ( stringifyExpression ) . join ( "" ) ;
}
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
const transformIf = createStructuralDirectiveTransform (
/^(if|else|else-if)$/ ,
( node , dir , context ) => {
2023-07-24 03:13:08 +00:00
return processIf ( node , dir , context , ( ifNode , branch , isRoot ) => {
2023-09-06 01:51:55 +00:00
const siblings = context . parent . children ;
let i = siblings . indexOf ( ifNode ) ;
let key = 0 ;
while ( i -- >= 0 ) {
const sibling = siblings [ i ] ;
if ( sibling && sibling . type === 9 ) {
key += sibling . branches . length ;
}
}
return ( ) => {
if ( isRoot ) {
ifNode . codegenNode = createCodegenNodeForBranch (
branch ,
key ,
context
) ;
} else {
const parentCondition = getParentCondition ( ifNode . codegenNode ) ;
parentCondition . alternate = createCodegenNodeForBranch (
branch ,
key + ifNode . branches . length - 1 ,
context
) ;
}
} ;
2023-07-24 03:13:08 +00:00
} ) ;
2023-09-06 01:51:55 +00:00
}
) ;
2023-07-24 03:13:08 +00:00
function processIf ( node , dir , context , processCodegen ) {
2023-09-06 01:51:55 +00:00
if ( dir . name !== "else" && ( ! dir . exp || ! dir . exp . content . trim ( ) ) ) {
const loc = dir . exp ? dir . exp . loc : node . loc ;
context . onError (
createCompilerError ( 28 , dir . loc )
) ;
dir . exp = createSimpleExpression ( ` true ` , false , loc ) ;
}
if ( dir . exp ) {
validateBrowserExpression ( dir . exp , context ) ;
}
if ( dir . name === "if" ) {
const branch = createIfBranch ( node , dir ) ;
const ifNode = {
type : 9 ,
loc : node . loc ,
branches : [ branch ]
} ;
context . replaceNode ( ifNode ) ;
if ( processCodegen ) {
return processCodegen ( ifNode , branch , true ) ;
}
} else {
const siblings = context . parent . children ;
const comments = [ ] ;
let i = siblings . indexOf ( node ) ;
while ( i -- >= - 1 ) {
const sibling = siblings [ i ] ;
if ( sibling && sibling . type === 3 ) {
context . removeNode ( sibling ) ;
comments . unshift ( sibling ) ;
continue ;
}
if ( sibling && sibling . type === 2 && ! sibling . content . trim ( ) . length ) {
context . removeNode ( sibling ) ;
continue ;
}
if ( sibling && sibling . type === 9 ) {
if ( dir . name === "else-if" && sibling . branches [ sibling . branches . length - 1 ] . condition === void 0 ) {
context . onError (
createCompilerError ( 30 , node . loc )
) ;
}
context . removeNode ( ) ;
2023-07-24 03:13:08 +00:00
const branch = createIfBranch ( node , dir ) ;
2023-09-06 01:51:55 +00:00
if ( comments . length && // #3619 ignore comments if the v-if is direct child of <transition>
! ( context . parent && context . parent . type === 1 && isBuiltInType ( context . parent . tag , "transition" ) ) ) {
branch . children = [ ... comments , ... branch . children ] ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
{
const key = branch . userKey ;
if ( key ) {
sibling . branches . forEach ( ( { userKey } ) => {
if ( isSameKey ( userKey , key ) ) {
context . onError (
createCompilerError (
29 ,
branch . userKey . loc
)
) ;
}
} ) ;
}
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
sibling . branches . push ( branch ) ;
const onExit = processCodegen && processCodegen ( sibling , branch , false ) ;
traverseNode ( branch , context ) ;
if ( onExit )
onExit ( ) ;
context . currentNode = null ;
} else {
context . onError (
createCompilerError ( 30 , node . loc )
) ;
}
break ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
2023-07-24 03:13:08 +00:00
}
function createIfBranch ( node , dir ) {
2023-09-06 01:51:55 +00:00
const isTemplateIf = node . tagType === 3 ;
return {
type : 10 ,
loc : node . loc ,
condition : dir . name === "else" ? void 0 : dir . exp ,
children : isTemplateIf && ! findDir ( node , "for" ) ? node . children : [ node ] ,
userKey : findProp ( node , ` key ` ) ,
isTemplateIf
} ;
2023-07-24 03:13:08 +00:00
}
function createCodegenNodeForBranch ( branch , keyIndex , context ) {
2023-09-06 01:51:55 +00:00
if ( branch . condition ) {
return createConditionalExpression (
branch . condition ,
createChildrenCodegenNode ( branch , keyIndex , context ) ,
// make sure to pass in asBlock: true so that the comment node call
// closes the current block.
createCallExpression ( context . helper ( CREATE _COMMENT ) , [
'"v-if"' ,
"true"
] )
) ;
} else {
return createChildrenCodegenNode ( branch , keyIndex , context ) ;
}
2023-07-24 03:13:08 +00:00
}
function createChildrenCodegenNode ( branch , keyIndex , context ) {
2023-09-06 01:51:55 +00:00
const { helper } = context ;
const keyProperty = createObjectProperty (
` key ` ,
createSimpleExpression (
` ${ keyIndex } ` ,
false ,
locStub ,
2
)
) ;
const { children } = branch ;
const firstChild = children [ 0 ] ;
const needFragmentWrapper = children . length !== 1 || firstChild . type !== 1 ;
if ( needFragmentWrapper ) {
if ( children . length === 1 && firstChild . type === 11 ) {
const vnodeCall = firstChild . codegenNode ;
injectProp ( vnodeCall , keyProperty , context ) ;
return vnodeCall ;
} else {
let patchFlag = 64 ;
let patchFlagText = PatchFlagNames [ 64 ] ;
if ( ! branch . isTemplateIf && children . filter ( ( c ) => c . type !== 3 ) . length === 1 ) {
patchFlag |= 2048 ;
patchFlagText += ` , ${ PatchFlagNames [ 2048 ] } ` ;
}
return createVNodeCall (
context ,
helper ( FRAGMENT ) ,
createObjectExpression ( [ keyProperty ] ) ,
children ,
patchFlag + ( ` /* ${ patchFlagText } */ ` ) ,
void 0 ,
void 0 ,
true ,
false ,
false ,
branch . loc
) ;
}
} else {
const ret = firstChild . codegenNode ;
const vnodeCall = getMemoedVNodeCall ( ret ) ;
if ( vnodeCall . type === 13 ) {
convertToBlock ( vnodeCall , context ) ;
}
injectProp ( vnodeCall , keyProperty , context ) ;
return ret ;
}
2023-07-24 03:13:08 +00:00
}
function isSameKey ( a , b ) {
2023-09-06 01:51:55 +00:00
if ( ! a || a . type !== b . type ) {
return false ;
}
if ( a . type === 6 ) {
if ( a . value . content !== b . value . content ) {
return false ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
} else {
const exp = a . exp ;
const branchExp = b . exp ;
if ( exp . type !== branchExp . type ) {
return false ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
if ( exp . type !== 4 || exp . isStatic !== branchExp . isStatic || exp . content !== branchExp . content ) {
return false ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
return true ;
2023-07-24 03:13:08 +00:00
}
function getParentCondition ( node ) {
2023-09-06 01:51:55 +00:00
while ( true ) {
if ( node . type === 19 ) {
if ( node . alternate . type === 19 ) {
node = node . alternate ;
} else {
return node ;
}
} else if ( node . type === 20 ) {
node = node . value ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
const transformFor = createStructuralDirectiveTransform (
"for" ,
( node , dir , context ) => {
2023-07-24 03:13:08 +00:00
const { helper , removeHelper } = context ;
2023-09-06 01:51:55 +00:00
return processFor ( node , dir , context , ( forNode ) => {
const renderExp = createCallExpression ( helper ( RENDER _LIST ) , [
forNode . source
] ) ;
const isTemplate = isTemplateNode ( node ) ;
const memo = findDir ( node , "memo" ) ;
const keyProp = findProp ( node , ` key ` ) ;
const keyExp = keyProp && ( keyProp . type === 6 ? createSimpleExpression ( keyProp . value . content , true ) : keyProp . exp ) ;
const keyProperty = keyProp ? createObjectProperty ( ` key ` , keyExp ) : null ;
const isStableFragment = forNode . source . type === 4 && forNode . source . constType > 0 ;
const fragmentFlag = isStableFragment ? 64 : keyProp ? 128 : 256 ;
forNode . codegenNode = createVNodeCall (
context ,
helper ( FRAGMENT ) ,
void 0 ,
renderExp ,
fragmentFlag + ( ` /* ${ PatchFlagNames [ fragmentFlag ] } */ ` ) ,
void 0 ,
void 0 ,
true ,
! isStableFragment ,
false ,
node . loc
) ;
return ( ) => {
let childBlock ;
const { children } = forNode ;
if ( isTemplate ) {
node . children . some ( ( c ) => {
if ( c . type === 1 ) {
const key = findProp ( c , "key" ) ;
if ( key ) {
context . onError (
createCompilerError (
33 ,
key . loc
)
) ;
return true ;
}
}
} ) ;
}
const needFragmentWrapper = children . length !== 1 || children [ 0 ] . type !== 1 ;
const slotOutlet = isSlotOutlet ( node ) ? node : isTemplate && node . children . length === 1 && isSlotOutlet ( node . children [ 0 ] ) ? node . children [ 0 ] : null ;
if ( slotOutlet ) {
childBlock = slotOutlet . codegenNode ;
if ( isTemplate && keyProperty ) {
injectProp ( childBlock , keyProperty , context ) ;
}
} else if ( needFragmentWrapper ) {
childBlock = createVNodeCall (
context ,
helper ( FRAGMENT ) ,
keyProperty ? createObjectExpression ( [ keyProperty ] ) : void 0 ,
node . children ,
64 + ( ` /* ${ PatchFlagNames [ 64 ] } */ ` ) ,
void 0 ,
void 0 ,
true ,
void 0 ,
false
/* isComponent */
) ;
} else {
childBlock = children [ 0 ] . codegenNode ;
if ( isTemplate && keyProperty ) {
injectProp ( childBlock , keyProperty , context ) ;
}
if ( childBlock . isBlock !== ! isStableFragment ) {
if ( childBlock . isBlock ) {
removeHelper ( OPEN _BLOCK ) ;
removeHelper (
getVNodeBlockHelper ( context . inSSR , childBlock . isComponent )
) ;
} else {
removeHelper (
getVNodeHelper ( context . inSSR , childBlock . isComponent )
) ;
}
}
childBlock . isBlock = ! isStableFragment ;
if ( childBlock . isBlock ) {
helper ( OPEN _BLOCK ) ;
helper ( getVNodeBlockHelper ( context . inSSR , childBlock . isComponent ) ) ;
} else {
helper ( getVNodeHelper ( context . inSSR , childBlock . isComponent ) ) ;
}
}
if ( memo ) {
const loop = createFunctionExpression (
createForLoopParams ( forNode . parseResult , [
createSimpleExpression ( ` _cached ` )
] )
) ;
loop . body = createBlockStatement ( [
createCompoundExpression ( [ ` const _memo = ( ` , memo . exp , ` ) ` ] ) ,
createCompoundExpression ( [
` if (_cached ` ,
... keyExp ? [ ` && _cached.key === ` , keyExp ] : [ ] ,
` && ${ context . helperString (
IS _MEMO _SAME
) } ( _cached , _memo ) ) return _cached `
] ) ,
createCompoundExpression ( [ ` const _item = ` , childBlock ] ) ,
createSimpleExpression ( ` _item.memo = _memo ` ) ,
createSimpleExpression ( ` return _item ` )
] ) ;
renderExp . arguments . push (
loop ,
createSimpleExpression ( ` _cache ` ) ,
createSimpleExpression ( String ( context . cached ++ ) )
) ;
} else {
renderExp . arguments . push (
createFunctionExpression (
createForLoopParams ( forNode . parseResult ) ,
childBlock ,
true
/* force newline */
)
) ;
}
} ;
2023-07-24 03:13:08 +00:00
} ) ;
2023-09-06 01:51:55 +00:00
}
) ;
2023-07-24 03:13:08 +00:00
function processFor ( node , dir , context , processCodegen ) {
2023-09-06 01:51:55 +00:00
if ( ! dir . exp ) {
context . onError (
createCompilerError ( 31 , dir . loc )
) ;
return ;
}
const parseResult = parseForExpression (
2023-07-24 03:13:08 +00:00
// can only be simple expression because vFor transform is applied
// before expression transform.
2023-09-06 01:51:55 +00:00
dir . exp ,
context
) ;
if ( ! parseResult ) {
context . onError (
createCompilerError ( 32 , dir . loc )
) ;
return ;
}
const { addIdentifiers , removeIdentifiers , scopes } = context ;
const { source , value , key , index } = parseResult ;
const forNode = {
type : 11 ,
loc : dir . loc ,
source ,
valueAlias : value ,
keyAlias : key ,
objectIndexAlias : index ,
parseResult ,
children : isTemplateNode ( node ) ? node . children : [ node ]
} ;
context . replaceNode ( forNode ) ;
scopes . vFor ++ ;
const onExit = processCodegen && processCodegen ( forNode ) ;
return ( ) => {
scopes . vFor -- ;
if ( onExit )
onExit ( ) ;
} ;
2023-07-24 03:13:08 +00:00
}
const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/ ;
const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/ ;
const stripParensRE = /^\(|\)$/g ;
function parseForExpression ( input , context ) {
2023-09-06 01:51:55 +00:00
const loc = input . loc ;
const exp = input . content ;
const inMatch = exp . match ( forAliasRE ) ;
if ( ! inMatch )
return ;
const [ , LHS , RHS ] = inMatch ;
const result = {
source : createAliasExpression (
loc ,
RHS . trim ( ) ,
exp . indexOf ( RHS , LHS . length )
) ,
value : void 0 ,
key : void 0 ,
index : void 0
} ;
{
validateBrowserExpression ( result . source , context ) ;
}
let valueContent = LHS . trim ( ) . replace ( stripParensRE , "" ) . trim ( ) ;
const trimmedOffset = LHS . indexOf ( valueContent ) ;
const iteratorMatch = valueContent . match ( forIteratorRE ) ;
if ( iteratorMatch ) {
valueContent = valueContent . replace ( forIteratorRE , "" ) . trim ( ) ;
const keyContent = iteratorMatch [ 1 ] . trim ( ) ;
let keyOffset ;
if ( keyContent ) {
keyOffset = exp . indexOf ( keyContent , trimmedOffset + valueContent . length ) ;
result . key = createAliasExpression ( loc , keyContent , keyOffset ) ;
{
validateBrowserExpression (
result . key ,
context ,
true
) ;
}
}
if ( iteratorMatch [ 2 ] ) {
const indexContent = iteratorMatch [ 2 ] . trim ( ) ;
if ( indexContent ) {
result . index = createAliasExpression (
loc ,
indexContent ,
exp . indexOf (
indexContent ,
result . key ? keyOffset + keyContent . length : trimmedOffset + valueContent . length
)
) ;
2023-07-24 03:13:08 +00:00
{
2023-09-06 01:51:55 +00:00
validateBrowserExpression (
result . index ,
context ,
true
) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
if ( valueContent ) {
result . value = createAliasExpression ( loc , valueContent , trimmedOffset ) ;
{
validateBrowserExpression (
result . value ,
context ,
true
) ;
}
}
return result ;
2023-07-24 03:13:08 +00:00
}
function createAliasExpression ( range , content , offset ) {
2023-09-06 01:51:55 +00:00
return createSimpleExpression (
content ,
false ,
getInnerRange ( range , offset , content . length )
) ;
2023-07-24 03:13:08 +00:00
}
function createForLoopParams ( { value , key , index } , memoArgs = [ ] ) {
2023-09-06 01:51:55 +00:00
return createParamsList ( [ value , key , index , ... memoArgs ] ) ;
2023-07-24 03:13:08 +00:00
}
function createParamsList ( args ) {
2023-09-06 01:51:55 +00:00
let i = args . length ;
while ( i -- ) {
if ( args [ i ] )
break ;
}
return args . slice ( 0 , i + 1 ) . map ( ( arg , i2 ) => arg || createSimpleExpression ( ` _ ` . repeat ( i2 + 1 ) , false ) ) ;
2023-07-24 03:13:08 +00:00
}
const defaultFallback = createSimpleExpression ( ` undefined ` , false ) ;
const trackSlotScopes = ( node , context ) => {
2023-09-06 01:51:55 +00:00
if ( node . type === 1 && ( node . tagType === 1 || node . tagType === 3 ) ) {
const vSlot = findDir ( node , "slot" ) ;
if ( vSlot ) {
vSlot . exp ;
context . scopes . vSlot ++ ;
return ( ) => {
context . scopes . vSlot -- ;
} ;
}
}
2023-07-24 03:13:08 +00:00
} ;
const trackVForSlotScopes = ( node , context ) => {
2023-09-06 01:51:55 +00:00
let vFor ;
if ( isTemplateNode ( node ) && node . props . some ( isVSlot ) && ( vFor = findDir ( node , "for" ) ) ) {
const result = vFor . parseResult = parseForExpression (
vFor . exp ,
context
) ;
if ( result ) {
const { value , key , index } = result ;
const { addIdentifiers , removeIdentifiers } = context ;
value && addIdentifiers ( value ) ;
key && addIdentifiers ( key ) ;
index && addIdentifiers ( index ) ;
return ( ) => {
value && removeIdentifiers ( value ) ;
key && removeIdentifiers ( key ) ;
index && removeIdentifiers ( index ) ;
} ;
}
}
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
const buildClientSlotFn = ( props , children , loc ) => createFunctionExpression (
props ,
children ,
false ,
true ,
children . length ? children [ 0 ] . loc : loc
) ;
2023-07-24 03:13:08 +00:00
function buildSlots ( node , context , buildSlotFn = buildClientSlotFn ) {
2023-09-06 01:51:55 +00:00
context . helper ( WITH _CTX ) ;
const { children , loc } = node ;
const slotsProperties = [ ] ;
const dynamicSlots = [ ] ;
let hasDynamicSlots = context . scopes . vSlot > 0 || context . scopes . vFor > 0 ;
const onComponentSlot = findDir ( node , "slot" , true ) ;
if ( onComponentSlot ) {
const { arg , exp } = onComponentSlot ;
if ( arg && ! isStaticExp ( arg ) ) {
hasDynamicSlots = true ;
}
slotsProperties . push (
createObjectProperty (
arg || createSimpleExpression ( "default" , true ) ,
buildSlotFn ( exp , children , loc )
)
) ;
}
let hasTemplateSlots = false ;
let hasNamedDefaultSlot = false ;
const implicitDefaultChildren = [ ] ;
const seenSlotNames = /* @__PURE__ */ new Set ( ) ;
let conditionalBranchIndex = 0 ;
for ( let i = 0 ; i < children . length ; i ++ ) {
const slotElement = children [ i ] ;
let slotDir ;
if ( ! isTemplateNode ( slotElement ) || ! ( slotDir = findDir ( slotElement , "slot" , true ) ) ) {
if ( slotElement . type !== 3 ) {
implicitDefaultChildren . push ( slotElement ) ;
}
continue ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
if ( onComponentSlot ) {
context . onError (
createCompilerError ( 37 , slotDir . loc )
) ;
break ;
}
hasTemplateSlots = true ;
const { children : slotChildren , loc : slotLoc } = slotElement ;
const {
arg : slotName = createSimpleExpression ( ` default ` , true ) ,
exp : slotProps ,
loc : dirLoc
} = slotDir ;
let staticSlotName ;
if ( isStaticExp ( slotName ) ) {
staticSlotName = slotName ? slotName . content : ` default ` ;
} else {
hasDynamicSlots = true ;
}
const slotFunction = buildSlotFn ( slotProps , slotChildren , slotLoc ) ;
let vIf ;
let vElse ;
let vFor ;
if ( vIf = findDir ( slotElement , "if" ) ) {
hasDynamicSlots = true ;
dynamicSlots . push (
createConditionalExpression (
vIf . exp ,
buildDynamicSlot ( slotName , slotFunction , conditionalBranchIndex ++ ) ,
defaultFallback
)
) ;
} else if ( vElse = findDir (
slotElement ,
/^else(-if)?$/ ,
true
/* allowEmpty */
) ) {
let j = i ;
let prev ;
while ( j -- ) {
prev = children [ j ] ;
if ( prev . type !== 3 ) {
break ;
}
}
if ( prev && isTemplateNode ( prev ) && findDir ( prev , "if" ) ) {
children . splice ( i , 1 ) ;
i -- ;
let conditional = dynamicSlots [ dynamicSlots . length - 1 ] ;
while ( conditional . alternate . type === 19 ) {
conditional = conditional . alternate ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
conditional . alternate = vElse . exp ? createConditionalExpression (
vElse . exp ,
buildDynamicSlot (
slotName ,
slotFunction ,
conditionalBranchIndex ++
) ,
defaultFallback
) : buildDynamicSlot ( slotName , slotFunction , conditionalBranchIndex ++ ) ;
} else {
context . onError (
createCompilerError ( 30 , vElse . loc )
) ;
}
} else if ( vFor = findDir ( slotElement , "for" ) ) {
hasDynamicSlots = true ;
const parseResult = vFor . parseResult || parseForExpression ( vFor . exp , context ) ;
if ( parseResult ) {
dynamicSlots . push (
createCallExpression ( context . helper ( RENDER _LIST ) , [
parseResult . source ,
createFunctionExpression (
createForLoopParams ( parseResult ) ,
buildDynamicSlot ( slotName , slotFunction ) ,
true
/* force newline */
)
] )
) ;
} else {
context . onError (
createCompilerError ( 32 , vFor . loc )
) ;
}
} else {
if ( staticSlotName ) {
if ( seenSlotNames . has ( staticSlotName ) ) {
context . onError (
createCompilerError (
38 ,
dirLoc
)
) ;
continue ;
}
seenSlotNames . add ( staticSlotName ) ;
if ( staticSlotName === "default" ) {
hasNamedDefaultSlot = true ;
}
}
slotsProperties . push ( createObjectProperty ( slotName , slotFunction ) ) ;
}
}
if ( ! onComponentSlot ) {
const buildDefaultSlotProperty = ( props , children2 ) => {
const fn = buildSlotFn ( props , children2 , loc ) ;
if ( context . compatConfig ) {
fn . isNonScopedSlot = true ;
}
return createObjectProperty ( ` default ` , fn ) ;
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
if ( ! hasTemplateSlots ) {
slotsProperties . push ( buildDefaultSlotProperty ( void 0 , children ) ) ;
} else if ( implicitDefaultChildren . length && // #3766
// with whitespace: 'preserve', whitespaces between slots will end up in
// implicitDefaultChildren. Ignore if all implicit children are whitespaces.
implicitDefaultChildren . some ( ( node2 ) => isNonWhitespaceContent ( node2 ) ) ) {
if ( hasNamedDefaultSlot ) {
context . onError (
createCompilerError (
39 ,
implicitDefaultChildren [ 0 ] . loc
)
) ;
} else {
slotsProperties . push (
buildDefaultSlotProperty ( void 0 , implicitDefaultChildren )
) ;
}
}
}
const slotFlag = hasDynamicSlots ? 2 : hasForwardedSlots ( node . children ) ? 3 : 1 ;
let slots = createObjectExpression (
slotsProperties . concat (
createObjectProperty (
` _ ` ,
// 2 = compiled but dynamic = can skip normalization, but must run diff
// 1 = compiled and static = can skip normalization AND diff as optimized
createSimpleExpression (
slotFlag + ( ` /* ${ slotFlagsText [ slotFlag ] } */ ` ) ,
false
)
)
) ,
loc
) ;
if ( dynamicSlots . length ) {
slots = createCallExpression ( context . helper ( CREATE _SLOTS ) , [
slots ,
createArrayExpression ( dynamicSlots )
] ) ;
}
return {
slots ,
hasDynamicSlots
} ;
2023-07-24 03:13:08 +00:00
}
function buildDynamicSlot ( name , fn , index ) {
2023-09-06 01:51:55 +00:00
const props = [
createObjectProperty ( ` name ` , name ) ,
createObjectProperty ( ` fn ` , fn )
] ;
if ( index != null ) {
props . push (
createObjectProperty ( ` key ` , createSimpleExpression ( String ( index ) , true ) )
) ;
}
return createObjectExpression ( props ) ;
2023-07-24 03:13:08 +00:00
}
function hasForwardedSlots ( children ) {
2023-09-06 01:51:55 +00:00
for ( let i = 0 ; i < children . length ; i ++ ) {
const child = children [ i ] ;
switch ( child . type ) {
case 1 :
if ( child . tagType === 2 || hasForwardedSlots ( child . children ) ) {
return true ;
}
break ;
case 9 :
if ( hasForwardedSlots ( child . branches ) )
return true ;
break ;
case 10 :
case 11 :
if ( hasForwardedSlots ( child . children ) )
return true ;
break ;
}
}
return false ;
2023-07-24 03:13:08 +00:00
}
function isNonWhitespaceContent ( node ) {
2023-09-06 01:51:55 +00:00
if ( node . type !== 2 && node . type !== 12 )
return true ;
return node . type === 2 ? ! ! node . content . trim ( ) : isNonWhitespaceContent ( node . content ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
const directiveImportMap = /* @__PURE__ */ new WeakMap ( ) ;
2023-07-24 03:13:08 +00:00
const transformElement = ( node , context ) => {
2023-09-06 01:51:55 +00:00
return function postTransformElement ( ) {
node = context . currentNode ;
if ( ! ( node . type === 1 && ( node . tagType === 0 || node . tagType === 1 ) ) ) {
return ;
}
const { tag , props } = node ;
const isComponent = node . tagType === 1 ;
let vnodeTag = isComponent ? resolveComponentType ( node , context ) : ` " ${ tag } " ` ;
const isDynamicComponent = isObject ( vnodeTag ) && vnodeTag . callee === RESOLVE _DYNAMIC _COMPONENT ;
let vnodeProps ;
let vnodeChildren ;
let vnodePatchFlag ;
let patchFlag = 0 ;
let vnodeDynamicProps ;
let dynamicPropNames ;
let vnodeDirectives ;
let shouldUseBlock = (
// dynamic component may resolve to plain elements
isDynamicComponent || vnodeTag === TELEPORT || vnodeTag === SUSPENSE || ! isComponent && // <svg> and <foreignObject> must be forced into blocks so that block
// updates inside get proper isSVG flag at runtime. (#639, #643)
// This is technically web-specific, but splitting the logic out of core
// leads to too much unnecessary complexity.
( tag === "svg" || tag === "foreignObject" )
) ;
if ( props . length > 0 ) {
const propsBuildResult = buildProps (
node ,
context ,
void 0 ,
isComponent ,
isDynamicComponent
) ;
vnodeProps = propsBuildResult . props ;
patchFlag = propsBuildResult . patchFlag ;
dynamicPropNames = propsBuildResult . dynamicPropNames ;
const directives = propsBuildResult . directives ;
vnodeDirectives = directives && directives . length ? createArrayExpression (
directives . map ( ( dir ) => buildDirectiveArgs ( dir , context ) )
) : void 0 ;
if ( propsBuildResult . shouldUseBlock ) {
shouldUseBlock = true ;
}
}
if ( node . children . length > 0 ) {
if ( vnodeTag === KEEP _ALIVE ) {
shouldUseBlock = true ;
patchFlag |= 1024 ;
if ( node . children . length > 1 ) {
context . onError (
createCompilerError ( 46 , {
start : node . children [ 0 ] . loc . start ,
end : node . children [ node . children . length - 1 ] . loc . end ,
source : ""
} )
) ;
}
}
const shouldBuildAsSlots = isComponent && // Teleport is not a real component and has dedicated runtime handling
vnodeTag !== TELEPORT && // explained above.
vnodeTag !== KEEP _ALIVE ;
if ( shouldBuildAsSlots ) {
const { slots , hasDynamicSlots } = buildSlots ( node , context ) ;
vnodeChildren = slots ;
if ( hasDynamicSlots ) {
patchFlag |= 1024 ;
}
} else if ( node . children . length === 1 && vnodeTag !== TELEPORT ) {
const child = node . children [ 0 ] ;
const type = child . type ;
const hasDynamicTextChild = type === 5 || type === 8 ;
if ( hasDynamicTextChild && getConstantType ( child , context ) === 0 ) {
patchFlag |= 1 ;
}
if ( hasDynamicTextChild || type === 2 ) {
vnodeChildren = child ;
} else {
vnodeChildren = node . children ;
}
} else {
vnodeChildren = node . children ;
}
}
if ( patchFlag !== 0 ) {
{
if ( patchFlag < 0 ) {
vnodePatchFlag = patchFlag + ` /* ${ PatchFlagNames [ patchFlag ] } */ ` ;
} else {
const flagNames = Object . keys ( PatchFlagNames ) . map ( Number ) . filter ( ( n ) => n > 0 && patchFlag & n ) . map ( ( n ) => PatchFlagNames [ n ] ) . join ( ` , ` ) ;
vnodePatchFlag = patchFlag + ` /* ${ flagNames } */ ` ;
}
}
if ( dynamicPropNames && dynamicPropNames . length ) {
vnodeDynamicProps = stringifyDynamicPropNames ( dynamicPropNames ) ;
}
}
node . codegenNode = createVNodeCall (
context ,
vnodeTag ,
vnodeProps ,
vnodeChildren ,
vnodePatchFlag ,
vnodeDynamicProps ,
vnodeDirectives ,
! ! shouldUseBlock ,
false ,
isComponent ,
node . loc
) ;
} ;
2023-07-24 03:13:08 +00:00
} ;
function resolveComponentType ( node , context , ssr = false ) {
2023-09-06 01:51:55 +00:00
let { tag } = node ;
const isExplicitDynamic = isComponentTag ( tag ) ;
const isProp = findProp ( node , "is" ) ;
if ( isProp ) {
if ( isExplicitDynamic || isCompatEnabled (
"COMPILER_IS_ON_ELEMENT" ,
context
) ) {
const exp = isProp . type === 6 ? isProp . value && createSimpleExpression ( isProp . value . content , true ) : isProp . exp ;
if ( exp ) {
2023-07-24 03:13:08 +00:00
return createCallExpression ( context . helper ( RESOLVE _DYNAMIC _COMPONENT ) , [
2023-09-06 01:51:55 +00:00
exp
2023-07-24 03:13:08 +00:00
] ) ;
2023-09-06 01:51:55 +00:00
}
} else if ( isProp . type === 6 && isProp . value . content . startsWith ( "vue:" ) ) {
tag = isProp . value . content . slice ( 4 ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
const isDir = ! isExplicitDynamic && findDir ( node , "is" ) ;
if ( isDir && isDir . exp ) {
{
context . onWarn (
createCompilerError ( 52 , isDir . loc )
) ;
}
return createCallExpression ( context . helper ( RESOLVE _DYNAMIC _COMPONENT ) , [
isDir . exp
] ) ;
}
const builtIn = isCoreComponent ( tag ) || context . isBuiltInComponent ( tag ) ;
if ( builtIn ) {
if ( ! ssr )
context . helper ( builtIn ) ;
return builtIn ;
}
context . helper ( RESOLVE _COMPONENT ) ;
context . components . add ( tag ) ;
return toValidAssetId ( tag , ` component ` ) ;
2023-07-24 03:13:08 +00:00
}
function buildProps ( node , context , props = node . props , isComponent , isDynamicComponent , ssr = false ) {
2023-09-06 01:51:55 +00:00
const { tag , loc : elementLoc , children } = node ;
let properties = [ ] ;
const mergeArgs = [ ] ;
const runtimeDirectives = [ ] ;
const hasChildren = children . length > 0 ;
let shouldUseBlock = false ;
let patchFlag = 0 ;
let hasRef = false ;
let hasClassBinding = false ;
let hasStyleBinding = false ;
let hasHydrationEventBinding = false ;
let hasDynamicKeys = false ;
let hasVnodeHook = false ;
const dynamicPropNames = [ ] ;
const pushMergeArg = ( arg ) => {
if ( properties . length ) {
mergeArgs . push (
createObjectExpression ( dedupeProperties ( properties ) , elementLoc )
) ;
properties = [ ] ;
}
if ( arg )
mergeArgs . push ( arg ) ;
} ;
const analyzePatchFlag = ( { key , value } ) => {
if ( isStaticExp ( key ) ) {
const name = key . content ;
const isEventHandler = isOn ( name ) ;
if ( isEventHandler && ( ! isComponent || isDynamicComponent ) && // omit the flag for click handlers because hydration gives click
// dedicated fast path.
name . toLowerCase ( ) !== "onclick" && // omit v-model handlers
name !== "onUpdate:modelValue" && // omit onVnodeXXX hooks
! isReservedProp ( name ) ) {
hasHydrationEventBinding = true ;
}
if ( isEventHandler && isReservedProp ( name ) ) {
hasVnodeHook = true ;
}
if ( value . type === 20 || ( value . type === 4 || value . type === 8 ) && getConstantType ( value , context ) > 0 ) {
return ;
}
if ( name === "ref" ) {
hasRef = true ;
} else if ( name === "class" ) {
hasClassBinding = true ;
} else if ( name === "style" ) {
hasStyleBinding = true ;
} else if ( name !== "key" && ! dynamicPropNames . includes ( name ) ) {
dynamicPropNames . push ( name ) ;
}
if ( isComponent && ( name === "class" || name === "style" ) && ! dynamicPropNames . includes ( name ) ) {
dynamicPropNames . push ( name ) ;
}
} else {
hasDynamicKeys = true ;
}
} ;
for ( let i = 0 ; i < props . length ; i ++ ) {
const prop = props [ i ] ;
if ( prop . type === 6 ) {
const { loc , name , value } = prop ;
let isStatic = true ;
if ( name === "ref" ) {
hasRef = true ;
if ( context . scopes . vFor > 0 ) {
properties . push (
createObjectProperty (
createSimpleExpression ( "ref_for" , true ) ,
createSimpleExpression ( "true" )
)
) ;
}
}
if ( name === "is" && ( isComponentTag ( tag ) || value && value . content . startsWith ( "vue:" ) || isCompatEnabled (
"COMPILER_IS_ON_ELEMENT" ,
context
) ) ) {
continue ;
}
properties . push (
createObjectProperty (
createSimpleExpression (
name ,
true ,
getInnerRange ( loc , 0 , name . length )
) ,
createSimpleExpression (
value ? value . content : "" ,
isStatic ,
value ? value . loc : loc
)
)
) ;
} else {
const { name , arg , exp , loc } = prop ;
const isVBind = name === "bind" ;
const isVOn = name === "on" ;
if ( name === "slot" ) {
if ( ! isComponent ) {
context . onError (
createCompilerError ( 40 , loc )
) ;
}
continue ;
}
if ( name === "once" || name === "memo" ) {
continue ;
}
if ( name === "is" || isVBind && isStaticArgOf ( arg , "is" ) && ( isComponentTag ( tag ) || isCompatEnabled (
"COMPILER_IS_ON_ELEMENT" ,
context
) ) ) {
continue ;
}
if ( isVOn && ssr ) {
continue ;
}
if (
// #938: elements with dynamic keys should be forced into blocks
isVBind && isStaticArgOf ( arg , "key" ) || // inline before-update hooks need to force block so that it is invoked
// before children
isVOn && hasChildren && isStaticArgOf ( arg , "vue:before-update" )
) {
shouldUseBlock = true ;
}
if ( isVBind && isStaticArgOf ( arg , "ref" ) && context . scopes . vFor > 0 ) {
properties . push (
createObjectProperty (
createSimpleExpression ( "ref_for" , true ) ,
createSimpleExpression ( "true" )
)
) ;
}
if ( ! arg && ( isVBind || isVOn ) ) {
hasDynamicKeys = true ;
if ( exp ) {
if ( isVBind ) {
pushMergeArg ( ) ;
{
{
const hasOverridableKeys = mergeArgs . some ( ( arg2 ) => {
if ( arg2 . type === 15 ) {
return arg2 . properties . some ( ( { key } ) => {
if ( key . type !== 4 || ! key . isStatic ) {
return true ;
}
return key . content !== "class" && key . content !== "style" && ! isOn ( key . content ) ;
} ) ;
} else {
return true ;
}
} ) ;
if ( hasOverridableKeys ) {
checkCompatEnabled (
"COMPILER_V_BIND_OBJECT_ORDER" ,
context ,
loc
) ;
}
}
if ( isCompatEnabled (
"COMPILER_V_BIND_OBJECT_ORDER" ,
context
) ) {
mergeArgs . unshift ( exp ) ;
continue ;
}
}
mergeArgs . push ( exp ) ;
} else {
pushMergeArg ( {
type : 14 ,
loc ,
callee : context . helper ( TO _HANDLERS ) ,
arguments : isComponent ? [ exp ] : [ exp , ` true ` ]
} ) ;
}
} else {
context . onError (
createCompilerError (
isVBind ? 34 : 35 ,
loc
)
) ;
}
continue ;
}
const directiveTransform = context . directiveTransforms [ name ] ;
if ( directiveTransform ) {
const { props : props2 , needRuntime } = directiveTransform ( prop , node , context ) ;
! ssr && props2 . forEach ( analyzePatchFlag ) ;
if ( isVOn && arg && ! isStaticExp ( arg ) ) {
pushMergeArg ( createObjectExpression ( props2 , elementLoc ) ) ;
} else {
properties . push ( ... props2 ) ;
}
if ( needRuntime ) {
runtimeDirectives . push ( prop ) ;
if ( isSymbol ( needRuntime ) ) {
directiveImportMap . set ( prop , needRuntime ) ;
}
}
} else if ( ! isBuiltInDirective ( name ) ) {
runtimeDirectives . push ( prop ) ;
if ( hasChildren ) {
shouldUseBlock = true ;
}
}
}
}
let propsExpression = void 0 ;
if ( mergeArgs . length ) {
pushMergeArg ( ) ;
if ( mergeArgs . length > 1 ) {
propsExpression = createCallExpression (
context . helper ( MERGE _PROPS ) ,
mergeArgs ,
elementLoc
) ;
} else {
propsExpression = mergeArgs [ 0 ] ;
}
} else if ( properties . length ) {
propsExpression = createObjectExpression (
dedupeProperties ( properties ) ,
elementLoc
) ;
}
if ( hasDynamicKeys ) {
patchFlag |= 16 ;
} else {
if ( hasClassBinding && ! isComponent ) {
patchFlag |= 2 ;
}
if ( hasStyleBinding && ! isComponent ) {
patchFlag |= 4 ;
}
if ( dynamicPropNames . length ) {
patchFlag |= 8 ;
}
if ( hasHydrationEventBinding ) {
patchFlag |= 32 ;
}
}
if ( ! shouldUseBlock && ( patchFlag === 0 || patchFlag === 32 ) && ( hasRef || hasVnodeHook || runtimeDirectives . length > 0 ) ) {
patchFlag |= 512 ;
}
if ( ! context . inSSR && propsExpression ) {
switch ( propsExpression . type ) {
case 15 :
let classKeyIndex = - 1 ;
let styleKeyIndex = - 1 ;
let hasDynamicKey = false ;
for ( let i = 0 ; i < propsExpression . properties . length ; i ++ ) {
const key = propsExpression . properties [ i ] . key ;
if ( isStaticExp ( key ) ) {
if ( key . content === "class" ) {
classKeyIndex = i ;
} else if ( key . content === "style" ) {
styleKeyIndex = i ;
}
} else if ( ! key . isHandlerKey ) {
hasDynamicKey = true ;
}
}
const classProp = propsExpression . properties [ classKeyIndex ] ;
const styleProp = propsExpression . properties [ styleKeyIndex ] ;
if ( ! hasDynamicKey ) {
if ( classProp && ! isStaticExp ( classProp . value ) ) {
classProp . value = createCallExpression (
context . helper ( NORMALIZE _CLASS ) ,
[ classProp . value ]
) ;
}
if ( styleProp && // the static style is compiled into an object,
// so use `hasStyleBinding` to ensure that it is a dynamic style binding
( hasStyleBinding || styleProp . value . type === 4 && styleProp . value . content . trim ( ) [ 0 ] === ` [ ` || // v-bind:style and style both exist,
// v-bind:style with static literal object
styleProp . value . type === 17 ) ) {
styleProp . value = createCallExpression (
context . helper ( NORMALIZE _STYLE ) ,
[ styleProp . value ]
) ;
}
} else {
propsExpression = createCallExpression (
context . helper ( NORMALIZE _PROPS ) ,
[ propsExpression ]
) ;
}
break ;
case 14 :
break ;
default :
propsExpression = createCallExpression (
context . helper ( NORMALIZE _PROPS ) ,
[
createCallExpression ( context . helper ( GUARD _REACTIVE _PROPS ) , [
propsExpression
] )
]
) ;
break ;
}
}
return {
props : propsExpression ,
directives : runtimeDirectives ,
patchFlag ,
dynamicPropNames ,
shouldUseBlock
} ;
2023-07-24 03:13:08 +00:00
}
function dedupeProperties ( properties ) {
2023-09-06 01:51:55 +00:00
const knownProps = /* @__PURE__ */ new Map ( ) ;
const deduped = [ ] ;
for ( let i = 0 ; i < properties . length ; i ++ ) {
const prop = properties [ i ] ;
if ( prop . key . type === 8 || ! prop . key . isStatic ) {
deduped . push ( prop ) ;
continue ;
}
const name = prop . key . content ;
const existing = knownProps . get ( name ) ;
if ( existing ) {
if ( name === "style" || name === "class" || isOn ( name ) ) {
mergeAsArray ( existing , prop ) ;
}
} else {
knownProps . set ( name , prop ) ;
deduped . push ( prop ) ;
}
}
return deduped ;
2023-07-24 03:13:08 +00:00
}
function mergeAsArray ( existing , incoming ) {
2023-09-06 01:51:55 +00:00
if ( existing . value . type === 17 ) {
existing . value . elements . push ( incoming . value ) ;
} else {
existing . value = createArrayExpression (
[ existing . value , incoming . value ] ,
existing . loc
) ;
}
2023-07-24 03:13:08 +00:00
}
function buildDirectiveArgs ( dir , context ) {
2023-09-06 01:51:55 +00:00
const dirArgs = [ ] ;
const runtime = directiveImportMap . get ( dir ) ;
if ( runtime ) {
dirArgs . push ( context . helperString ( runtime ) ) ;
} else {
{
context . helper ( RESOLVE _DIRECTIVE ) ;
context . directives . add ( dir . name ) ;
dirArgs . push ( toValidAssetId ( dir . name , ` directive ` ) ) ;
}
}
const { loc } = dir ;
if ( dir . exp )
dirArgs . push ( dir . exp ) ;
if ( dir . arg ) {
if ( ! dir . exp ) {
dirArgs . push ( ` void 0 ` ) ;
}
dirArgs . push ( dir . arg ) ;
}
if ( Object . keys ( dir . modifiers ) . length ) {
if ( ! dir . arg ) {
if ( ! dir . exp ) {
dirArgs . push ( ` void 0 ` ) ;
}
dirArgs . push ( ` void 0 ` ) ;
}
const trueExpression = createSimpleExpression ( ` true ` , false , loc ) ;
dirArgs . push (
createObjectExpression (
dir . modifiers . map (
( modifier ) => createObjectProperty ( modifier , trueExpression )
) ,
loc
)
) ;
}
return createArrayExpression ( dirArgs , dir . loc ) ;
2023-07-24 03:13:08 +00:00
}
function stringifyDynamicPropNames ( props ) {
2023-09-06 01:51:55 +00:00
let propsNamesString = ` [ ` ;
for ( let i = 0 , l = props . length ; i < l ; i ++ ) {
propsNamesString += JSON . stringify ( props [ i ] ) ;
if ( i < l - 1 )
propsNamesString += ", " ;
}
return propsNamesString + ` ] ` ;
2023-07-24 03:13:08 +00:00
}
function isComponentTag ( tag ) {
2023-09-06 01:51:55 +00:00
return tag === "component" || tag === "Component" ;
2023-07-24 03:13:08 +00:00
}
const transformSlotOutlet = ( node , context ) => {
2023-09-06 01:51:55 +00:00
if ( isSlotOutlet ( node ) ) {
const { children , loc } = node ;
const { slotName , slotProps } = processSlotOutlet ( node , context ) ;
const slotArgs = [
context . prefixIdentifiers ? ` _ctx. $ slots ` : ` $ slots ` ,
slotName ,
"{}" ,
"undefined" ,
"true"
] ;
let expectedLen = 2 ;
if ( slotProps ) {
slotArgs [ 2 ] = slotProps ;
expectedLen = 3 ;
}
if ( children . length ) {
slotArgs [ 3 ] = createFunctionExpression ( [ ] , children , false , false , loc ) ;
expectedLen = 4 ;
}
if ( context . scopeId && ! context . slotted ) {
expectedLen = 5 ;
}
slotArgs . splice ( expectedLen ) ;
node . codegenNode = createCallExpression (
context . helper ( RENDER _SLOT ) ,
slotArgs ,
loc
) ;
}
2023-07-24 03:13:08 +00:00
} ;
function processSlotOutlet ( node , context ) {
2023-09-06 01:51:55 +00:00
let slotName = ` "default" ` ;
let slotProps = void 0 ;
const nonNameProps = [ ] ;
for ( let i = 0 ; i < node . props . length ; i ++ ) {
const p = node . props [ i ] ;
if ( p . type === 6 ) {
if ( p . value ) {
if ( p . name === "name" ) {
slotName = JSON . stringify ( p . value . content ) ;
} else {
p . name = camelize ( p . name ) ;
nonNameProps . push ( p ) ;
}
}
} else {
if ( p . name === "bind" && isStaticArgOf ( p . arg , "name" ) ) {
if ( p . exp )
slotName = p . exp ;
} else {
if ( p . name === "bind" && p . arg && isStaticExp ( p . arg ) ) {
p . arg . content = camelize ( p . arg . content ) ;
}
nonNameProps . push ( p ) ;
}
}
}
if ( nonNameProps . length > 0 ) {
const { props , directives } = buildProps (
node ,
context ,
nonNameProps ,
false ,
false
) ;
slotProps = props ;
if ( directives . length ) {
context . onError (
createCompilerError (
36 ,
directives [ 0 ] . loc
)
) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
}
return {
slotName ,
slotProps
} ;
2023-07-24 03:13:08 +00:00
}
const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/ ;
2023-09-06 01:51:55 +00:00
const transformOn$1 = ( dir , node , context , augmentor ) => {
const { loc , modifiers , arg } = dir ;
if ( ! dir . exp && ! modifiers . length ) {
context . onError ( createCompilerError ( 35 , loc ) ) ;
}
let eventName ;
if ( arg . type === 4 ) {
if ( arg . isStatic ) {
let rawName = arg . content ;
if ( rawName . startsWith ( "vnode" ) ) {
context . onWarn (
createCompilerError ( 51 , arg . loc )
) ;
}
if ( rawName . startsWith ( "vue:" ) ) {
rawName = ` vnode- ${ rawName . slice ( 4 ) } ` ;
}
const eventString = node . tagType !== 0 || rawName . startsWith ( "vnode" ) || ! /[A-Z]/ . test ( rawName ) ? (
// for non-element and vnode lifecycle event listeners, auto convert
// it to camelCase. See issue #2249
toHandlerKey ( camelize ( rawName ) )
) : (
// preserve case for plain element listeners that have uppercase
// letters, as these may be custom elements' custom events
` on: ${ rawName } `
) ;
eventName = createSimpleExpression ( eventString , true , arg . loc ) ;
} else {
eventName = createCompoundExpression ( [
` ${ context . helperString ( TO _HANDLER _KEY ) } ( ` ,
arg ,
` ) `
] ) ;
}
} else {
eventName = arg ;
eventName . children . unshift ( ` ${ context . helperString ( TO _HANDLER _KEY ) } ( ` ) ;
eventName . children . push ( ` ) ` ) ;
}
let exp = dir . exp ;
if ( exp && ! exp . content . trim ( ) ) {
exp = void 0 ;
}
let shouldCache = context . cacheHandlers && ! exp && ! context . inVOnce ;
if ( exp ) {
const isMemberExp = isMemberExpression ( exp . content ) ;
const isInlineStatement = ! ( isMemberExp || fnExpRE . test ( exp . content ) ) ;
const hasMultipleStatements = exp . content . includes ( ` ; ` ) ;
{
validateBrowserExpression (
exp ,
context ,
false ,
hasMultipleStatements
) ;
}
if ( isInlineStatement || shouldCache && isMemberExp ) {
exp = createCompoundExpression ( [
` ${ isInlineStatement ? ` $ event ` : ` ${ ` ` } (...args) ` } => ${ hasMultipleStatements ? ` { ` : ` ( ` } ` ,
exp ,
hasMultipleStatements ? ` } ` : ` ) `
] ) ;
}
}
let ret = {
props : [
createObjectProperty (
eventName ,
exp || createSimpleExpression ( ` () => {} ` , false , loc )
)
]
} ;
if ( augmentor ) {
ret = augmentor ( ret ) ;
}
if ( shouldCache ) {
ret . props [ 0 ] . value = context . cache ( ret . props [ 0 ] . value ) ;
}
ret . props . forEach ( ( p ) => p . key . isHandlerKey = true ) ;
return ret ;
2023-07-24 03:13:08 +00:00
} ;
const transformBind = ( dir , _node , context ) => {
2023-09-06 01:51:55 +00:00
const { exp , modifiers , loc } = dir ;
const arg = dir . arg ;
if ( arg . type !== 4 ) {
arg . children . unshift ( ` ( ` ) ;
arg . children . push ( ` ) || "" ` ) ;
} else if ( ! arg . isStatic ) {
arg . content = ` ${ arg . content } || "" ` ;
}
if ( modifiers . includes ( "camel" ) ) {
if ( arg . type === 4 ) {
if ( arg . isStatic ) {
arg . content = camelize ( arg . content ) ;
} else {
arg . content = ` ${ context . helperString ( CAMELIZE ) } ( ${ arg . content } ) ` ;
}
} else {
arg . children . unshift ( ` ${ context . helperString ( CAMELIZE ) } ( ` ) ;
arg . children . push ( ` ) ` ) ;
}
}
if ( ! context . inSSR ) {
if ( modifiers . includes ( "prop" ) ) {
injectPrefix ( arg , "." ) ;
}
if ( modifiers . includes ( "attr" ) ) {
injectPrefix ( arg , "^" ) ;
}
}
if ( ! exp || exp . type === 4 && ! exp . content . trim ( ) ) {
context . onError ( createCompilerError ( 34 , loc ) ) ;
2023-07-24 03:13:08 +00:00
return {
2023-09-06 01:51:55 +00:00
props : [ createObjectProperty ( arg , createSimpleExpression ( "" , true , loc ) ) ]
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
}
return {
props : [ createObjectProperty ( arg , exp ) ]
} ;
2023-07-24 03:13:08 +00:00
} ;
const injectPrefix = ( arg , prefix ) => {
2023-09-06 01:51:55 +00:00
if ( arg . type === 4 ) {
if ( arg . isStatic ) {
arg . content = prefix + arg . content ;
} else {
arg . content = ` \` ${ prefix } \$ { ${ arg . content } } \` ` ;
}
} else {
arg . children . unshift ( ` ' ${ prefix } ' + ( ` ) ;
arg . children . push ( ` ) ` ) ;
}
2023-07-24 03:13:08 +00:00
} ;
const transformText = ( node , context ) => {
2023-09-06 01:51:55 +00:00
if ( node . type === 0 || node . type === 1 || node . type === 11 || node . type === 10 ) {
return ( ) => {
const children = node . children ;
let currentContainer = void 0 ;
let hasText = false ;
for ( let i = 0 ; i < children . length ; i ++ ) {
const child = children [ i ] ;
if ( isText$1 ( child ) ) {
hasText = true ;
for ( let j = i + 1 ; j < children . length ; j ++ ) {
const next = children [ j ] ;
if ( isText$1 ( next ) ) {
if ( ! currentContainer ) {
currentContainer = children [ i ] = createCompoundExpression (
[ child ] ,
child . loc
) ;
}
currentContainer . children . push ( ` + ` , next ) ;
children . splice ( j , 1 ) ;
j -- ;
} else {
currentContainer = void 0 ;
break ;
}
}
}
}
if ( ! hasText || // if this is a plain element with a single text child, leave it
// as-is since the runtime has dedicated fast path for this by directly
// setting textContent of the element.
// for component root it's always normalized anyway.
children . length === 1 && ( node . type === 0 || node . type === 1 && node . tagType === 0 && // #3756
// custom directives can potentially add DOM elements arbitrarily,
// we need to avoid setting textContent of the element at runtime
// to avoid accidentally overwriting the DOM elements added
// by the user through custom directives.
! node . props . find (
( p ) => p . type === 7 && ! context . directiveTransforms [ p . name ]
) && // in compat mode, <template> tags with no special directives
// will be rendered as a fragment so its children must be
// converted into vnodes.
! ( node . tag === "template" ) ) ) {
return ;
}
for ( let i = 0 ; i < children . length ; i ++ ) {
const child = children [ i ] ;
if ( isText$1 ( child ) || child . type === 8 ) {
const callArgs = [ ] ;
if ( child . type !== 2 || child . content !== " " ) {
callArgs . push ( child ) ;
}
if ( ! context . ssr && getConstantType ( child , context ) === 0 ) {
callArgs . push (
1 + ( ` /* ${ PatchFlagNames [ 1 ] } */ ` )
) ;
}
children [ i ] = {
type : 12 ,
content : child ,
loc : child . loc ,
codegenNode : createCallExpression (
context . helper ( CREATE _TEXT ) ,
callArgs
)
} ;
}
}
} ;
}
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
const seen$1 = /* @__PURE__ */ new WeakSet ( ) ;
2023-07-24 03:13:08 +00:00
const transformOnce = ( node , context ) => {
2023-09-06 01:51:55 +00:00
if ( node . type === 1 && findDir ( node , "once" , true ) ) {
if ( seen$1 . has ( node ) || context . inVOnce || context . inSSR ) {
return ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
seen$1 . add ( node ) ;
context . inVOnce = true ;
context . helper ( SET _BLOCK _TRACKING ) ;
return ( ) => {
context . inVOnce = false ;
const cur = context . currentNode ;
if ( cur . codegenNode ) {
cur . codegenNode = context . cache (
cur . codegenNode ,
true
/* isVNode */
) ;
}
} ;
}
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
const transformModel$1 = ( dir , node , context ) => {
const { exp , arg } = dir ;
if ( ! exp ) {
context . onError (
createCompilerError ( 41 , dir . loc )
) ;
return createTransformProps ( ) ;
}
const rawExp = exp . loc . source ;
const expString = exp . type === 4 ? exp . content : rawExp ;
const bindingType = context . bindingMetadata [ rawExp ] ;
if ( bindingType === "props" || bindingType === "props-aliased" ) {
context . onError ( createCompilerError ( 44 , exp . loc ) ) ;
return createTransformProps ( ) ;
}
const maybeRef = false ;
if ( ! expString . trim ( ) || ! isMemberExpression ( expString ) && ! maybeRef ) {
context . onError (
createCompilerError ( 42 , exp . loc )
) ;
return createTransformProps ( ) ;
}
const propName = arg ? arg : createSimpleExpression ( "modelValue" , true ) ;
const eventName = arg ? isStaticExp ( arg ) ? ` onUpdate: ${ camelize ( arg . content ) } ` : createCompoundExpression ( [ '"onUpdate:" + ' , arg ] ) : ` onUpdate:modelValue ` ;
let assignmentExp ;
const eventArg = context . isTS ? ` ( $ event: any) ` : ` $ event ` ;
{
assignmentExp = createCompoundExpression ( [
` ${ eventArg } => (( ` ,
exp ,
` ) = $ event) `
] ) ;
}
const props = [
// modelValue: foo
createObjectProperty ( propName , dir . exp ) ,
// "onUpdate:modelValue": $event => (foo = $event)
createObjectProperty ( eventName , assignmentExp )
] ;
if ( dir . modifiers . length && node . tagType === 1 ) {
const modifiers = dir . modifiers . map ( ( m ) => ( isSimpleIdentifier ( m ) ? m : JSON . stringify ( m ) ) + ` : true ` ) . join ( ` , ` ) ;
const modifiersKey = arg ? isStaticExp ( arg ) ? ` ${ arg . content } Modifiers ` : createCompoundExpression ( [ arg , ' + "Modifiers"' ] ) : ` modelModifiers ` ;
props . push (
createObjectProperty (
modifiersKey ,
createSimpleExpression (
` { ${ modifiers } } ` ,
false ,
dir . loc ,
2
)
)
) ;
}
return createTransformProps ( props ) ;
2023-07-24 03:13:08 +00:00
} ;
function createTransformProps ( props = [ ] ) {
2023-09-06 01:51:55 +00:00
return { props } ;
2023-07-24 03:13:08 +00:00
}
const validDivisionCharRE = /[\w).+\-_$\]]/ ;
const transformFilter = ( node , context ) => {
2023-09-06 01:51:55 +00:00
if ( ! isCompatEnabled ( "COMPILER_FILTER" , context ) ) {
return ;
}
if ( node . type === 5 ) {
rewriteFilter ( node . content , context ) ;
}
if ( node . type === 1 ) {
node . props . forEach ( ( prop ) => {
if ( prop . type === 7 && prop . name !== "for" && prop . exp ) {
rewriteFilter ( prop . exp , context ) ;
}
} ) ;
}
2023-07-24 03:13:08 +00:00
} ;
function rewriteFilter ( node , context ) {
2023-09-06 01:51:55 +00:00
if ( node . type === 4 ) {
parseFilter ( node , context ) ;
} else {
for ( let i = 0 ; i < node . children . length ; i ++ ) {
const child = node . children [ i ] ;
if ( typeof child !== "object" )
continue ;
if ( child . type === 4 ) {
parseFilter ( child , context ) ;
} else if ( child . type === 8 ) {
rewriteFilter ( node , context ) ;
} else if ( child . type === 5 ) {
rewriteFilter ( child . content , context ) ;
}
}
}
2023-07-24 03:13:08 +00:00
}
function parseFilter ( node , context ) {
2023-09-06 01:51:55 +00:00
const exp = node . content ;
let inSingle = false ;
let inDouble = false ;
let inTemplateString = false ;
let inRegex = false ;
let curly = 0 ;
let square = 0 ;
let paren = 0 ;
let lastFilterIndex = 0 ;
let c , prev , i , expression , filters = [ ] ;
for ( i = 0 ; i < exp . length ; i ++ ) {
prev = c ;
c = exp . charCodeAt ( i ) ;
if ( inSingle ) {
if ( c === 39 && prev !== 92 )
inSingle = false ;
} else if ( inDouble ) {
if ( c === 34 && prev !== 92 )
inDouble = false ;
} else if ( inTemplateString ) {
if ( c === 96 && prev !== 92 )
inTemplateString = false ;
} else if ( inRegex ) {
if ( c === 47 && prev !== 92 )
inRegex = false ;
} else if ( c === 124 && // pipe
exp . charCodeAt ( i + 1 ) !== 124 && exp . charCodeAt ( i - 1 ) !== 124 && ! curly && ! square && ! paren ) {
if ( expression === void 0 ) {
lastFilterIndex = i + 1 ;
2023-07-24 03:13:08 +00:00
expression = exp . slice ( 0 , i ) . trim ( ) ;
2023-09-06 01:51:55 +00:00
} else {
2023-07-24 03:13:08 +00:00
pushFilter ( ) ;
2023-09-06 01:51:55 +00:00
}
} else {
switch ( c ) {
case 34 :
inDouble = true ;
break ;
case 39 :
inSingle = true ;
break ;
case 96 :
inTemplateString = true ;
break ;
case 40 :
paren ++ ;
break ;
case 41 :
paren -- ;
break ;
case 91 :
square ++ ;
break ;
case 93 :
square -- ;
break ;
case 123 :
curly ++ ;
break ;
case 125 :
curly -- ;
break ;
}
if ( c === 47 ) {
let j = i - 1 ;
let p ;
for ( ; j >= 0 ; j -- ) {
p = exp . charAt ( j ) ;
if ( p !== " " )
break ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
if ( ! p || ! validDivisionCharRE . test ( p ) ) {
inRegex = true ;
}
}
}
}
if ( expression === void 0 ) {
expression = exp . slice ( 0 , i ) . trim ( ) ;
} else if ( lastFilterIndex !== 0 ) {
pushFilter ( ) ;
}
function pushFilter ( ) {
filters . push ( exp . slice ( lastFilterIndex , i ) . trim ( ) ) ;
lastFilterIndex = i + 1 ;
}
if ( filters . length ) {
warnDeprecation (
"COMPILER_FILTER" ,
context ,
node . loc
) ;
for ( i = 0 ; i < filters . length ; i ++ ) {
expression = wrapFilter ( expression , filters [ i ] , context ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
node . content = expression ;
}
2023-07-24 03:13:08 +00:00
}
function wrapFilter ( exp , filter , context ) {
2023-09-06 01:51:55 +00:00
context . helper ( RESOLVE _FILTER ) ;
const i = filter . indexOf ( "(" ) ;
if ( i < 0 ) {
context . filters . add ( filter ) ;
return ` ${ toValidAssetId ( filter , "filter" ) } ( ${ exp } ) ` ;
} else {
const name = filter . slice ( 0 , i ) ;
const args = filter . slice ( i + 1 ) ;
context . filters . add ( name ) ;
return ` ${ toValidAssetId ( name , "filter" ) } ( ${ exp } ${ args !== ")" ? "," + args : args } ` ;
}
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
const seen = /* @__PURE__ */ new WeakSet ( ) ;
2023-07-24 03:13:08 +00:00
const transformMemo = ( node , context ) => {
2023-09-06 01:51:55 +00:00
if ( node . type === 1 ) {
const dir = findDir ( node , "memo" ) ;
if ( ! dir || seen . has ( node ) ) {
return ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
seen . add ( node ) ;
return ( ) => {
const codegenNode = node . codegenNode || context . currentNode . codegenNode ;
if ( codegenNode && codegenNode . type === 13 ) {
if ( node . tagType !== 1 ) {
convertToBlock ( codegenNode , context ) ;
}
node . codegenNode = createCallExpression ( context . helper ( WITH _MEMO ) , [
dir . exp ,
createFunctionExpression ( void 0 , codegenNode ) ,
` _cache ` ,
String ( context . cached ++ )
] ) ;
}
} ;
}
2023-07-24 03:13:08 +00:00
} ;
function getBaseTransformPreset ( prefixIdentifiers ) {
2023-09-06 01:51:55 +00:00
return [
[
transformOnce ,
transformIf ,
transformMemo ,
transformFor ,
... [ transformFilter ] ,
... [ transformExpression ] ,
transformSlotOutlet ,
transformElement ,
trackSlotScopes ,
transformText
] ,
2023-07-24 03:13:08 +00:00
{
2023-09-06 01:51:55 +00:00
on : transformOn$1 ,
bind : transformBind ,
model : transformModel$1
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
] ;
}
function baseCompile ( template , options = { } ) {
const onError = options . onError || defaultOnError ;
const isModuleMode = options . mode === "module" ;
{
if ( options . prefixIdentifiers === true ) {
onError ( createCompilerError ( 47 ) ) ;
} else if ( isModuleMode ) {
onError ( createCompilerError ( 48 ) ) ;
}
}
const prefixIdentifiers = false ;
if ( options . cacheHandlers ) {
onError ( createCompilerError ( 49 ) ) ;
}
if ( options . scopeId && ! isModuleMode ) {
onError ( createCompilerError ( 50 ) ) ;
}
const ast = isString ( template ) ? baseParse ( template , options ) : template ;
const [ nodeTransforms , directiveTransforms ] = getBaseTransformPreset ( ) ;
transform (
ast ,
extend ( { } , options , {
prefixIdentifiers ,
nodeTransforms : [
... nodeTransforms ,
... options . nodeTransforms || [ ]
// user transforms
] ,
directiveTransforms : extend (
{ } ,
directiveTransforms ,
options . directiveTransforms || { }
// user transforms
)
} )
) ;
return generate (
ast ,
extend ( { } , options , {
prefixIdentifiers
} )
) ;
2023-07-24 03:13:08 +00:00
}
const noopDirectiveTransform = ( ) => ( { props : [ ] } ) ;
const V _MODEL _RADIO = Symbol ( ` vModelRadio ` ) ;
const V _MODEL _CHECKBOX = Symbol ( ` vModelCheckbox ` ) ;
const V _MODEL _TEXT = Symbol ( ` vModelText ` ) ;
const V _MODEL _SELECT = Symbol ( ` vModelSelect ` ) ;
const V _MODEL _DYNAMIC = Symbol ( ` vModelDynamic ` ) ;
const V _ON _WITH _MODIFIERS = Symbol ( ` vOnModifiersGuard ` ) ;
const V _ON _WITH _KEYS = Symbol ( ` vOnKeysGuard ` ) ;
const V _SHOW = Symbol ( ` vShow ` ) ;
const TRANSITION = Symbol ( ` Transition ` ) ;
const TRANSITION _GROUP = Symbol ( ` TransitionGroup ` ) ;
registerRuntimeHelpers ( {
2023-09-06 01:51:55 +00:00
[ V _MODEL _RADIO ] : ` vModelRadio ` ,
[ V _MODEL _CHECKBOX ] : ` vModelCheckbox ` ,
[ V _MODEL _TEXT ] : ` vModelText ` ,
[ V _MODEL _SELECT ] : ` vModelSelect ` ,
[ V _MODEL _DYNAMIC ] : ` vModelDynamic ` ,
[ V _ON _WITH _MODIFIERS ] : ` withModifiers ` ,
[ V _ON _WITH _KEYS ] : ` withKeys ` ,
[ V _SHOW ] : ` vShow ` ,
[ TRANSITION ] : ` Transition ` ,
[ TRANSITION _GROUP ] : ` TransitionGroup `
2023-07-24 03:13:08 +00:00
} ) ;
let decoder ;
function decodeHtmlBrowser ( raw , asAttr = false ) {
2023-09-06 01:51:55 +00:00
if ( ! decoder ) {
decoder = document . createElement ( "div" ) ;
}
if ( asAttr ) {
decoder . innerHTML = ` <div foo=" ${ raw . replace ( /"/g , """ ) } "> ` ;
return decoder . children [ 0 ] . getAttribute ( "foo" ) ;
} else {
decoder . innerHTML = raw ;
return decoder . textContent ;
}
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
const isRawTextContainer = /* @__PURE__ */ makeMap (
"style,iframe,script,noscript" ,
true
) ;
2023-07-24 03:13:08 +00:00
const parserOptions = {
2023-09-06 01:51:55 +00:00
isVoidTag ,
isNativeTag : ( tag ) => isHTMLTag ( tag ) || isSVGTag ( tag ) ,
isPreTag : ( tag ) => tag === "pre" ,
decodeEntities : decodeHtmlBrowser ,
isBuiltInComponent : ( tag ) => {
if ( isBuiltInType ( tag , ` Transition ` ) ) {
return TRANSITION ;
} else if ( isBuiltInType ( tag , ` TransitionGroup ` ) ) {
return TRANSITION _GROUP ;
}
} ,
// https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
getNamespace ( tag , parent ) {
let ns = parent ? parent . ns : 0 ;
if ( parent && ns === 2 ) {
if ( parent . tag === "annotation-xml" ) {
if ( tag === "svg" ) {
return 1 ;
}
if ( parent . props . some (
( a ) => a . type === 6 && a . name === "encoding" && a . value != null && ( a . value . content === "text/html" || a . value . content === "application/xhtml+xml" )
) ) {
ns = 0 ;
}
} else if ( /^m(?:[ions]|text)$/ . test ( parent . tag ) && tag !== "mglyph" && tag !== "malignmark" ) {
ns = 0 ;
}
} else if ( parent && ns === 1 ) {
if ( parent . tag === "foreignObject" || parent . tag === "desc" || parent . tag === "title" ) {
ns = 0 ;
}
}
if ( ns === 0 ) {
if ( tag === "svg" ) {
return 1 ;
}
if ( tag === "math" ) {
return 2 ;
}
}
return ns ;
} ,
// https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
getTextMode ( { tag , ns } ) {
if ( ns === 0 ) {
if ( tag === "textarea" || tag === "title" ) {
return 1 ;
}
if ( isRawTextContainer ( tag ) ) {
return 2 ;
}
}
return 0 ;
}
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
const transformStyle = ( node ) => {
if ( node . type === 1 ) {
node . props . forEach ( ( p , i ) => {
if ( p . type === 6 && p . name === "style" && p . value ) {
node . props [ i ] = {
type : 7 ,
name : ` bind ` ,
arg : createSimpleExpression ( ` style ` , true , p . loc ) ,
exp : parseInlineCSS ( p . value . content , p . loc ) ,
modifiers : [ ] ,
loc : p . loc
} ;
}
} ) ;
}
2023-07-24 03:13:08 +00:00
} ;
const parseInlineCSS = ( cssText , loc ) => {
2023-09-06 01:51:55 +00:00
const normalized = parseStringStyle ( cssText ) ;
return createSimpleExpression (
JSON . stringify ( normalized ) ,
false ,
loc ,
3
) ;
2023-07-24 03:13:08 +00:00
} ;
function createDOMCompilerError ( code , loc ) {
2023-09-06 01:51:55 +00:00
return createCompilerError (
code ,
loc ,
DOMErrorMessages
) ;
2023-07-24 03:13:08 +00:00
}
const DOMErrorMessages = {
2023-09-06 01:51:55 +00:00
[ 53 ] : ` v-html is missing expression. ` ,
[ 54 ] : ` v-html will override element children. ` ,
[ 55 ] : ` v-text is missing expression. ` ,
[ 56 ] : ` v-text will override element children. ` ,
[ 57 ] : ` v-model can only be used on <input>, <textarea> and <select> elements. ` ,
[ 58 ] : ` v-model argument is not supported on plain elements. ` ,
[ 59 ] : ` v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead. ` ,
[ 60 ] : ` Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior. ` ,
[ 61 ] : ` v-show is missing expression. ` ,
[ 62 ] : ` <Transition> expects exactly one child element or component. ` ,
[ 63 ] : ` Tags with side effect (<script> and <style>) are ignored in client component templates. `
2023-07-24 03:13:08 +00:00
} ;
const transformVHtml = ( dir , node , context ) => {
2023-09-06 01:51:55 +00:00
const { exp , loc } = dir ;
if ( ! exp ) {
context . onError (
createDOMCompilerError ( 53 , loc )
) ;
}
if ( node . children . length ) {
context . onError (
createDOMCompilerError ( 54 , loc )
) ;
node . children . length = 0 ;
}
return {
props : [
createObjectProperty (
createSimpleExpression ( ` innerHTML ` , true , loc ) ,
exp || createSimpleExpression ( "" , true )
)
]
} ;
2023-07-24 03:13:08 +00:00
} ;
const transformVText = ( dir , node , context ) => {
2023-09-06 01:51:55 +00:00
const { exp , loc } = dir ;
if ( ! exp ) {
context . onError (
createDOMCompilerError ( 55 , loc )
) ;
}
if ( node . children . length ) {
context . onError (
createDOMCompilerError ( 56 , loc )
) ;
node . children . length = 0 ;
}
return {
props : [
createObjectProperty (
createSimpleExpression ( ` textContent ` , true ) ,
exp ? getConstantType ( exp , context ) > 0 ? exp : createCallExpression (
context . helperString ( TO _DISPLAY _STRING ) ,
[ exp ] ,
loc
) : createSimpleExpression ( "" , true )
)
]
} ;
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
const transformModel = ( dir , node , context ) => {
const baseResult = transformModel$1 ( dir , node , context ) ;
if ( ! baseResult . props . length || node . tagType === 1 ) {
2023-07-24 03:13:08 +00:00
return baseResult ;
2023-09-06 01:51:55 +00:00
}
if ( dir . arg ) {
context . onError (
createDOMCompilerError (
58 ,
dir . arg . loc
)
) ;
}
function checkDuplicatedValue ( ) {
const value = findProp ( node , "value" ) ;
if ( value ) {
context . onError (
createDOMCompilerError (
60 ,
value . loc
)
) ;
}
}
const { tag } = node ;
const isCustomElement = context . isCustomElement ( tag ) ;
if ( tag === "input" || tag === "textarea" || tag === "select" || isCustomElement ) {
let directiveToUse = V _MODEL _TEXT ;
let isInvalidType = false ;
if ( tag === "input" || isCustomElement ) {
const type = findProp ( node , ` type ` ) ;
if ( type ) {
if ( type . type === 7 ) {
directiveToUse = V _MODEL _DYNAMIC ;
} else if ( type . value ) {
switch ( type . value . content ) {
case "radio" :
directiveToUse = V _MODEL _RADIO ;
break ;
case "checkbox" :
directiveToUse = V _MODEL _CHECKBOX ;
break ;
case "file" :
isInvalidType = true ;
context . onError (
createDOMCompilerError (
59 ,
dir . loc
)
) ;
break ;
default :
checkDuplicatedValue ( ) ;
break ;
}
}
} else if ( hasDynamicKeyVBind ( node ) ) {
directiveToUse = V _MODEL _DYNAMIC ;
} else {
checkDuplicatedValue ( ) ;
}
} else if ( tag === "select" ) {
directiveToUse = V _MODEL _SELECT ;
} else {
checkDuplicatedValue ( ) ;
}
if ( ! isInvalidType ) {
baseResult . needRuntime = context . helper ( directiveToUse ) ;
}
} else {
context . onError (
createDOMCompilerError (
57 ,
dir . loc
)
) ;
}
baseResult . props = baseResult . props . filter (
( p ) => ! ( p . key . type === 4 && p . key . content === "modelValue" )
) ;
return baseResult ;
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
const isEventOptionModifier = /* @__PURE__ */ makeMap ( ` passive,once,capture ` ) ;
const isNonKeyModifier = /* @__PURE__ */ makeMap (
// event propagation management
` stop,prevent,self,ctrl,shift,alt,meta,exact,middle `
) ;
const maybeKeyModifier = /* @__PURE__ */ makeMap ( "left,right" ) ;
const isKeyboardEvent = /* @__PURE__ */ makeMap (
` onkeyup,onkeydown,onkeypress ` ,
true
) ;
2023-07-24 03:13:08 +00:00
const resolveModifiers = ( key , modifiers , context , loc ) => {
2023-09-06 01:51:55 +00:00
const keyModifiers = [ ] ;
const nonKeyModifiers = [ ] ;
const eventOptionModifiers = [ ] ;
for ( let i = 0 ; i < modifiers . length ; i ++ ) {
const modifier = modifiers [ i ] ;
if ( modifier === "native" && checkCompatEnabled (
"COMPILER_V_ON_NATIVE" ,
context ,
loc
) ) {
eventOptionModifiers . push ( modifier ) ;
} else if ( isEventOptionModifier ( modifier ) ) {
eventOptionModifiers . push ( modifier ) ;
} else {
if ( maybeKeyModifier ( modifier ) ) {
if ( isStaticExp ( key ) ) {
if ( isKeyboardEvent ( key . content ) ) {
keyModifiers . push ( modifier ) ;
} else {
nonKeyModifiers . push ( modifier ) ;
}
} else {
keyModifiers . push ( modifier ) ;
nonKeyModifiers . push ( modifier ) ;
}
} else {
if ( isNonKeyModifier ( modifier ) ) {
nonKeyModifiers . push ( modifier ) ;
} else {
keyModifiers . push ( modifier ) ;
}
}
}
}
return {
keyModifiers ,
nonKeyModifiers ,
eventOptionModifiers
} ;
2023-07-24 03:13:08 +00:00
} ;
const transformClick = ( key , event ) => {
2023-09-06 01:51:55 +00:00
const isStaticClick = isStaticExp ( key ) && key . content . toLowerCase ( ) === "onclick" ;
return isStaticClick ? createSimpleExpression ( event , true ) : key . type !== 4 ? createCompoundExpression ( [
` ( ` ,
key ,
` ) === "onClick" ? " ${ event } " : ( ` ,
key ,
` ) `
] ) : key ;
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
const transformOn = ( dir , node , context ) => {
return transformOn$1 ( dir , node , context , ( baseResult ) => {
const { modifiers } = dir ;
if ( ! modifiers . length )
return baseResult ;
let { key , value : handlerExp } = baseResult . props [ 0 ] ;
const { keyModifiers , nonKeyModifiers , eventOptionModifiers } = resolveModifiers ( key , modifiers , context , dir . loc ) ;
if ( nonKeyModifiers . includes ( "right" ) ) {
key = transformClick ( key , ` onContextmenu ` ) ;
}
if ( nonKeyModifiers . includes ( "middle" ) ) {
key = transformClick ( key , ` onMouseup ` ) ;
}
if ( nonKeyModifiers . length ) {
handlerExp = createCallExpression ( context . helper ( V _ON _WITH _MODIFIERS ) , [
handlerExp ,
JSON . stringify ( nonKeyModifiers )
] ) ;
}
if ( keyModifiers . length && // if event name is dynamic, always wrap with keys guard
( ! isStaticExp ( key ) || isKeyboardEvent ( key . content ) ) ) {
handlerExp = createCallExpression ( context . helper ( V _ON _WITH _KEYS ) , [
handlerExp ,
JSON . stringify ( keyModifiers )
] ) ;
}
if ( eventOptionModifiers . length ) {
const modifierPostfix = eventOptionModifiers . map ( capitalize ) . join ( "" ) ;
key = isStaticExp ( key ) ? createSimpleExpression ( ` ${ key . content } ${ modifierPostfix } ` , true ) : createCompoundExpression ( [ ` ( ` , key , ` ) + " ${ modifierPostfix } " ` ] ) ;
2023-07-24 03:13:08 +00:00
}
return {
2023-09-06 01:51:55 +00:00
props : [ createObjectProperty ( key , handlerExp ) ]
2023-07-24 03:13:08 +00:00
} ;
2023-09-06 01:51:55 +00:00
} ) ;
} ;
const transformShow = ( dir , node , context ) => {
const { exp , loc } = dir ;
if ( ! exp ) {
context . onError (
createDOMCompilerError ( 61 , loc )
) ;
}
return {
props : [ ] ,
needRuntime : context . helper ( V _SHOW )
} ;
2023-07-24 03:13:08 +00:00
} ;
const transformTransition = ( node , context ) => {
2023-09-06 01:51:55 +00:00
if ( node . type === 1 && node . tagType === 1 ) {
const component = context . isBuiltInComponent ( node . tag ) ;
if ( component === TRANSITION ) {
return ( ) => {
if ( ! node . children . length ) {
return ;
}
if ( hasMultipleChildren ( node ) ) {
context . onError (
createDOMCompilerError (
62 ,
{
start : node . children [ 0 ] . loc . start ,
end : node . children [ node . children . length - 1 ] . loc . end ,
source : ""
}
)
) ;
}
const child = node . children [ 0 ] ;
if ( child . type === 1 ) {
for ( const p of child . props ) {
if ( p . type === 7 && p . name === "show" ) {
node . props . push ( {
type : 6 ,
name : "persisted" ,
value : void 0 ,
loc : node . loc
} ) ;
}
}
}
} ;
}
}
2023-07-24 03:13:08 +00:00
} ;
function hasMultipleChildren ( node ) {
2023-09-06 01:51:55 +00:00
const children = node . children = node . children . filter (
( c ) => c . type !== 3 && ! ( c . type === 2 && ! c . content . trim ( ) )
) ;
const child = children [ 0 ] ;
return children . length !== 1 || child . type === 11 || child . type === 9 && child . branches . some ( hasMultipleChildren ) ;
2023-07-24 03:13:08 +00:00
}
const ignoreSideEffectTags = ( node , context ) => {
2023-09-06 01:51:55 +00:00
if ( node . type === 1 && node . tagType === 0 && ( node . tag === "script" || node . tag === "style" ) ) {
context . onError (
createDOMCompilerError (
63 ,
node . loc
)
) ;
context . removeNode ( ) ;
}
2023-07-24 03:13:08 +00:00
} ;
const DOMNodeTransforms = [
2023-09-06 01:51:55 +00:00
transformStyle ,
... [ transformTransition ]
2023-07-24 03:13:08 +00:00
] ;
const DOMDirectiveTransforms = {
2023-09-06 01:51:55 +00:00
cloak : noopDirectiveTransform ,
html : transformVHtml ,
text : transformVText ,
model : transformModel ,
// override compiler-core
on : transformOn ,
// override compiler-core
show : transformShow
2023-07-24 03:13:08 +00:00
} ;
function compile ( template , options = { } ) {
2023-09-06 01:51:55 +00:00
return baseCompile (
template ,
extend ( { } , parserOptions , options , {
nodeTransforms : [
// ignore <script> and <tag>
// this is not put inside DOMNodeTransforms because that list is used
// by compiler-ssr to generate vnode fallback branches
ignoreSideEffectTags ,
... DOMNodeTransforms ,
... options . nodeTransforms || [ ]
] ,
directiveTransforms : extend (
{ } ,
DOMDirectiveTransforms ,
options . directiveTransforms || { }
) ,
transformHoist : null
} )
) ;
2023-07-24 03:13:08 +00:00
}
function parse ( template , options = { } ) {
2023-09-06 01:51:55 +00:00
return baseParse ( template , extend ( { } , parserOptions , options ) ) ;
2023-07-24 03:13:08 +00:00
}
2023-09-06 01:51:55 +00:00
export { BASE _TRANSITION , CAMELIZE , CAPITALIZE , CREATE _BLOCK , CREATE _COMMENT , CREATE _ELEMENT _BLOCK , CREATE _ELEMENT _VNODE , CREATE _SLOTS , CREATE _STATIC , CREATE _TEXT , CREATE _VNODE , DOMDirectiveTransforms , DOMNodeTransforms , FRAGMENT , GUARD _REACTIVE _PROPS , IS _MEMO _SAME , IS _REF , KEEP _ALIVE , MERGE _PROPS , NORMALIZE _CLASS , NORMALIZE _PROPS , NORMALIZE _STYLE , OPEN _BLOCK , POP _SCOPE _ID , PUSH _SCOPE _ID , RENDER _LIST , RENDER _SLOT , RESOLVE _COMPONENT , RESOLVE _DIRECTIVE , RESOLVE _DYNAMIC _COMPONENT , RESOLVE _FILTER , SET _BLOCK _TRACKING , SUSPENSE , TELEPORT , TO _DISPLAY _STRING , TO _HANDLERS , TO _HANDLER _KEY , TRANSITION , TRANSITION _GROUP , TS _NODE _TYPES , UNREF , V _MODEL _CHECKBOX , V _MODEL _DYNAMIC , V _MODEL _RADIO , V _MODEL _SELECT , V _MODEL _TEXT , V _ON _WITH _KEYS , V _ON _WITH _MODIFIERS , V _SHOW , WITH _CTX , WITH _DIRECTIVES , WITH _MEMO , advancePositionWithClone , advancePositionWithMutation , assert , baseCompile , baseParse , buildDirectiveArgs , buildProps , buildSlots , checkCompatEnabled , compile , convertToBlock , createArrayExpression , createAssignmentExpression , createBlockStatement , createCacheExpression , createCallExpression , createCompilerError , createCompoundExpression , createConditionalExpression , createDOMCompilerError , createForLoopParams , createFunctionExpression , createIfStatement , createInterpolation , createObjectExpression , createObjectProperty , createReturnStatement , createRoot , createSequenceExpression , createSimpleExpression , createStructuralDirectiveTransform , createTemplateLiteral , createTransformContext , createVNodeCall , extractIdentifiers , findDir , findProp , generate , generateCodeFrame , getBaseTransformPreset , getConstantType , getInnerRange , getMemoedVNodeCall , getVNodeBlockHelper , getVNodeHelper , hasDynamicKeyVBind , hasScopeRef , helperNameMap , injectProp , isBuiltInType , isCoreComponent , isFunctionType , isInDestructureAssignment , isMemberExpression , isMemberExpressionBrowser , isMemberExpressionNode , isReferencedIdentifier , isSimpleIdentifier , isSlotOutlet , isStaticArgOf , isStaticExp , isStaticProperty , isStaticPropertyKey , isTemplateNode , isText$1 as isText , isVSlot , locStub , noopDirectiveTransform , parse , parserOptions , processExpression , processFor , processIf , processSlotOutlet , registerRuntimeHelpers , resolveComponentType , stringifyExpression , toValidAssetId , trackSlotScopes , trackVForSlotScopes , transform , transformBind , transformElement , transformExpression , transformModel$1 as transformModel , transformOn$1 as transformOn , transformStyle , traverseNode , walkBlockDeclarations , walkFunctionParams , walkIdentifiers , warnDeprecation } ;