parse() — vue Function Reference
Architecture documentation for the parse() function in index.ts from the vue codebase.
Entity Profile
Dependency Diagram
graph TD c27f0203_4eed_0348_4118_e8e105adc6ee["parse()"] af57cd20_c4ce_0877_c02c_52056ca04d4a["compileScript()"] af57cd20_c4ce_0877_c02c_52056ca04d4a -->|calls| c27f0203_4eed_0348_4118_e8e105adc6ee 0eb11b52_7b12_f1cc_ae13_a11bead27b1a["createCompiler()"] 0eb11b52_7b12_f1cc_ae13_a11bead27b1a -->|calls| c27f0203_4eed_0348_4118_e8e105adc6ee 4a6c1fba_4814_b3d9_ff02_8fe63201f887["createCompiler()"] 4a6c1fba_4814_b3d9_ff02_8fe63201f887 -->|calls| c27f0203_4eed_0348_4118_e8e105adc6ee 3db86199_9b4d_9828_3e37_09eaa549b4c0["assertCodegen()"] 3db86199_9b4d_9828_3e37_09eaa549b4c0 -->|calls| c27f0203_4eed_0348_4118_e8e105adc6ee 60be7ac1_6434_fac4_f5be_94ad5b9caab5["pluckModuleFunction()"] c27f0203_4eed_0348_4118_e8e105adc6ee -->|calls| 60be7ac1_6434_fac4_f5be_94ad5b9caab5 02a69150_0003_c070_7030_ea511121f64b["processElement()"] c27f0203_4eed_0348_4118_e8e105adc6ee -->|calls| 02a69150_0003_c070_7030_ea511121f64b 06e12792_ae17_ac23_460b_7d8d7b5605d2["addIfCondition()"] c27f0203_4eed_0348_4118_e8e105adc6ee -->|calls| 06e12792_ae17_ac23_460b_7d8d7b5605d2 b0895ac7_be65_09b3_28ea_cc60452a3e8d["processIfConditions()"] c27f0203_4eed_0348_4118_e8e105adc6ee -->|calls| b0895ac7_be65_09b3_28ea_cc60452a3e8d fd20e96f_b55a_0f3e_cf28_09b6a919ed0d["parseHTML()"] c27f0203_4eed_0348_4118_e8e105adc6ee -->|calls| fd20e96f_b55a_0f3e_cf28_09b6a919ed0d 0485f3cb_c3b3_9bf3_1eed_c0cc3e1c9ee0["guardIESVGBug()"] c27f0203_4eed_0348_4118_e8e105adc6ee -->|calls| 0485f3cb_c3b3_9bf3_1eed_c0cc3e1c9ee0 c3257530_0ca9_f5ae_06ab_082337103cbe["createASTElement()"] c27f0203_4eed_0348_4118_e8e105adc6ee -->|calls| c3257530_0ca9_f5ae_06ab_082337103cbe 26654f22_9c12_fe5f_5055_41e02cec4701["isForbiddenTag()"] c27f0203_4eed_0348_4118_e8e105adc6ee -->|calls| 26654f22_9c12_fe5f_5055_41e02cec4701 0dc15f71_d03a_2c68_db25_fced0d610bab["isServerRendering()"] c27f0203_4eed_0348_4118_e8e105adc6ee -->|calls| 0dc15f71_d03a_2c68_db25_fced0d610bab 1d30a4e6_ee89_3e00_4ee8_32812b74d0d0["processPre()"] c27f0203_4eed_0348_4118_e8e105adc6ee -->|calls| 1d30a4e6_ee89_3e00_4ee8_32812b74d0d0 style c27f0203_4eed_0348_4118_e8e105adc6ee fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
src/compiler/parser/index.ts lines 86–422
export function parse(template: string, options: CompilerOptions): ASTElement {
warn = options.warn || baseWarn
platformIsPreTag = options.isPreTag || no
platformMustUseProp = options.mustUseProp || no
platformGetTagNamespace = options.getTagNamespace || no
const isReservedTag = options.isReservedTag || no
maybeComponent = (el: ASTElement) =>
!!(
el.component ||
el.attrsMap[':is'] ||
el.attrsMap['v-bind:is'] ||
!(el.attrsMap.is ? isReservedTag(el.attrsMap.is) : isReservedTag(el.tag))
)
transforms = pluckModuleFunction(options.modules, 'transformNode')
preTransforms = pluckModuleFunction(options.modules, 'preTransformNode')
postTransforms = pluckModuleFunction(options.modules, 'postTransformNode')
delimiters = options.delimiters
const stack: any[] = []
const preserveWhitespace = options.preserveWhitespace !== false
const whitespaceOption = options.whitespace
let root
let currentParent
let inVPre = false
let inPre = false
let warned = false
function warnOnce(msg, range) {
if (!warned) {
warned = true
warn(msg, range)
}
}
function closeElement(element) {
trimEndingWhitespace(element)
if (!inVPre && !element.processed) {
element = processElement(element, options)
}
// tree management
if (!stack.length && element !== root) {
// allow root elements with v-if, v-else-if and v-else
if (root.if && (element.elseif || element.else)) {
if (__DEV__) {
checkRootConstraints(element)
}
addIfCondition(root, {
exp: element.elseif,
block: element
})
} else if (__DEV__) {
warnOnce(
`Component template should contain exactly one root element. ` +
`If you are using v-if on multiple elements, ` +
`use v-else-if to chain them instead.`,
{ start: element.start }
)
}
}
if (currentParent && !element.forbidden) {
if (element.elseif || element.else) {
processIfConditions(element, currentParent)
} else {
if (element.slotScope) {
// scoped slot
// keep it in the children list so that v-else(-if) conditions can
// find it as the prev node.
const name = element.slotTarget || '"default"'
;(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[
name
] = element
}
currentParent.children.push(element)
element.parent = currentParent
}
}
// final children cleanup
// filter out scoped slots
element.children = element.children.filter(c => !c.slotScope)
// remove trailing whitespace node again
trimEndingWhitespace(element)
// check pre state
if (element.pre) {
inVPre = false
}
if (platformIsPreTag(element.tag)) {
inPre = false
}
// apply post-transforms
for (let i = 0; i < postTransforms.length; i++) {
postTransforms[i](element, options)
}
}
function trimEndingWhitespace(el) {
// remove trailing whitespace node
if (!inPre) {
let lastNode
while (
(lastNode = el.children[el.children.length - 1]) &&
lastNode.type === 3 &&
lastNode.text === ' '
) {
el.children.pop()
}
}
}
function checkRootConstraints(el) {
if (el.tag === 'slot' || el.tag === 'template') {
warnOnce(
`Cannot use <${el.tag}> as component root element because it may ` +
'contain multiple nodes.',
{ start: el.start }
)
}
if (el.attrsMap.hasOwnProperty('v-for')) {
warnOnce(
'Cannot use v-for on stateful component root element because ' +
'it renders multiple elements.',
el.rawAttrsMap['v-for']
)
}
}
parseHTML(template, {
warn,
expectHTML: options.expectHTML,
isUnaryTag: options.isUnaryTag,
canBeLeftOpenTag: options.canBeLeftOpenTag,
shouldDecodeNewlines: options.shouldDecodeNewlines,
shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
shouldKeepComment: options.comments,
outputSourceRange: options.outputSourceRange,
start(tag, attrs, unary, start, end) {
// check namespace.
// inherit parent ns if there is one
const ns =
(currentParent && currentParent.ns) || platformGetTagNamespace(tag)
// handle IE svg bug
/* istanbul ignore if */
if (isIE && ns === 'svg') {
attrs = guardIESVGBug(attrs)
}
let element: ASTElement = createASTElement(tag, attrs, currentParent)
if (ns) {
element.ns = ns
}
if (__DEV__) {
if (options.outputSourceRange) {
element.start = start
element.end = end
element.rawAttrsMap = element.attrsList.reduce((cumulated, attr) => {
cumulated[attr.name] = attr
return cumulated
}, {})
}
attrs.forEach(attr => {
if (invalidAttributeRE.test(attr.name)) {
warn(
`Invalid dynamic argument expression: attribute names cannot contain ` +
`spaces, quotes, <, >, / or =.`,
options.outputSourceRange
? {
start: attr.start! + attr.name.indexOf(`[`),
end: attr.start! + attr.name.length
}
: undefined
)
}
})
}
if (isForbiddenTag(element) && !isServerRendering()) {
element.forbidden = true
__DEV__ &&
warn(
'Templates should only be responsible for mapping the state to the ' +
'UI. Avoid placing tags with side-effects in your templates, such as ' +
`<${tag}>` +
', as they will not be parsed.',
{ start: element.start }
)
}
// apply pre-transforms
for (let i = 0; i < preTransforms.length; i++) {
element = preTransforms[i](element, options) || element
}
if (!inVPre) {
processPre(element)
if (element.pre) {
inVPre = true
}
}
if (platformIsPreTag(element.tag)) {
inPre = true
}
if (inVPre) {
processRawAttrs(element)
} else if (!element.processed) {
// structural directives
processFor(element)
processIf(element)
processOnce(element)
}
if (!root) {
root = element
if (__DEV__) {
checkRootConstraints(root)
}
}
if (!unary) {
currentParent = element
stack.push(element)
} else {
closeElement(element)
}
},
end(tag, start, end) {
const element = stack[stack.length - 1]
// pop stack
stack.length -= 1
currentParent = stack[stack.length - 1]
if (__DEV__ && options.outputSourceRange) {
element.end = end
}
closeElement(element)
},
chars(text: string, start?: number, end?: number) {
if (!currentParent) {
if (__DEV__) {
if (text === template) {
warnOnce(
'Component template requires a root element, rather than just text.',
{ start }
)
} else if ((text = text.trim())) {
warnOnce(`text "${text}" outside root element will be ignored.`, {
start
})
}
}
return
}
// IE textarea placeholder bug
/* istanbul ignore if */
if (
isIE &&
currentParent.tag === 'textarea' &&
currentParent.attrsMap.placeholder === text
) {
return
}
const children = currentParent.children
if (inPre || text.trim()) {
text = isTextTag(currentParent)
? text
: (decodeHTMLCached(text) as string)
} else if (!children.length) {
// remove the whitespace-only node right after an opening tag
text = ''
} else if (whitespaceOption) {
if (whitespaceOption === 'condense') {
// in condense mode, remove the whitespace node if it contains
// line break, otherwise condense to a single space
text = lineBreakRE.test(text) ? '' : ' '
} else {
text = ' '
}
} else {
text = preserveWhitespace ? ' ' : ''
}
if (text) {
if (!inPre && whitespaceOption === 'condense') {
// condense consecutive whitespaces into single space
text = text.replace(whitespaceRE, ' ')
}
let res
let child: ASTNode | undefined
if (!inVPre && text !== ' ' && (res = parseText(text, delimiters))) {
child = {
type: 2,
expression: res.expression,
tokens: res.tokens,
text
}
} else if (
text !== ' ' ||
!children.length ||
children[children.length - 1].text !== ' '
) {
child = {
type: 3,
text
}
}
if (child) {
if (__DEV__ && options.outputSourceRange) {
child.start = start
child.end = end
}
children.push(child)
}
}
},
comment(text: string, start, end) {
// adding anything as a sibling to the root node is forbidden
// comments should still be allowed, but ignored
if (currentParent) {
const child: ASTText = {
type: 3,
text,
isComment: true
}
if (__DEV__ && options.outputSourceRange) {
child.start = start
child.end = end
}
currentParent.children.push(child)
}
}
})
return root
}
Domain
Subdomains
Calls
Source
Frequently Asked Questions
What does parse() do?
parse() is a function in the vue codebase.
What does parse() call?
parse() calls 16 function(s): addIfCondition, createASTElement, guardIESVGBug, isForbiddenTag, isServerRendering, isTextTag, parseHTML, parseText, and 8 more.
What calls parse()?
parse() is called by 4 function(s): assertCodegen, compileScript, createCompiler, createCompiler.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free