onopentagname(start, end) {
const name = getSlice(start, end)
- // in SFC mode, root-level tags locations are for its inner content.
- const startIndex = tokenizer.inSFCRoot
- ? end + fastForward(end, CharCodes.Gt) + 1
- : start - 1
currentOpenTag = {
type: NodeTypes.ELEMENT,
tag: name,
tagType: ElementTypes.ELEMENT, // will be refined on tag close
props: [],
children: [],
- loc: getLoc(startIndex, end),
+ loc: getLoc(start - 1, end),
codegenNode: undefined
}
+ if (tokenizer.inSFCRoot) {
+ // in SFC mode, generate locations for root-level tags' inner content.
+ currentOpenTag.innerLoc = getLoc(
+ end + fastForward(end, CharCodes.Gt) + 1,
+ end
+ )
+ }
},
onopentagend(end) {
function onCloseTag(el: ElementNode, end: number, isImplied = false) {
// attach end position
- if (tokenizer.inSFCRoot) {
- // SFC root tag, end position should be inner end
- if (el.children.length) {
- el.loc.end = extend({}, el.children[el.children.length - 1].loc.end)
- } else {
- el.loc.end = extend({}, el.loc.start)
- }
- } else if (isImplied) {
+ if (isImplied) {
// implied close, end should be backtracked to close
el.loc.end = tokenizer.getPos(backTrack(end, CharCodes.Lt))
} else {
el.loc.end = tokenizer.getPos(end + fastForward(end, CharCodes.Gt) + 1)
}
+ if (tokenizer.inSFCRoot) {
+ // SFC root tag, resolve inner end
+ if (el.children.length) {
+ el.innerLoc!.end = extend({}, el.children[el.children.length - 1].loc.end)
+ } else {
+ el.innerLoc!.end = extend({}, el.innerLoc!.start)
+ }
+ }
+
// refine element type
const { tag, ns } = el
if (!inVPre) {
pad: SFCParseOptions['pad']
): SFCBlock {
const type = node.tag
+ const loc = node.innerLoc!
const attrs: Record<string, string | true> = {}
const block: SFCBlock = {
type,
- content: source.slice(node.loc.start.offset, node.loc.end.offset),
- loc: node.loc,
+ content: source.slice(loc.start.offset, loc.end.offset),
+ loc,
attrs
}
if (pad) {