feat(compiler-sfc): handle pad option (#509)

This commit is contained in:
likui
2019-12-02 23:43:30 +08:00
committed by Evan You
parent 08a1de5e29
commit ef2786151e
2 changed files with 76 additions and 9 deletions

View File

@@ -14,7 +14,7 @@ export interface SFCParseOptions {
needMap?: boolean
filename?: string
sourceRoot?: string
pad?: 'line' | 'space'
pad?: boolean | 'line' | 'space'
}
export interface SFCBlock {
@@ -61,7 +61,7 @@ export function parse(
pad = 'line'
}: SFCParseOptions = {}
): SFCDescriptor {
const sourceKey = source + needMap + filename + sourceRoot
const sourceKey = source + needMap + filename + sourceRoot + pad
const cache = sourceToSFC.get(sourceKey)
if (cache) {
return cache
@@ -87,27 +87,26 @@ export function parse(
if (!node.children.length) {
return
}
// TODO handle pad option
switch (node.tag) {
case 'template':
if (!sfc.template) {
sfc.template = createBlock(node) as SFCTemplateBlock
sfc.template = createBlock(node, source, pad) as SFCTemplateBlock
} else {
warnDuplicateBlock(source, filename, node)
}
break
case 'script':
if (!sfc.script) {
sfc.script = createBlock(node) as SFCScriptBlock
sfc.script = createBlock(node, source, pad) as SFCScriptBlock
} else {
warnDuplicateBlock(source, filename, node)
}
break
case 'style':
sfc.styles.push(createBlock(node) as SFCStyleBlock)
sfc.styles.push(createBlock(node, source, pad) as SFCStyleBlock)
break
default:
sfc.customBlocks.push(createBlock(node))
sfc.customBlocks.push(createBlock(node, source, pad))
break
}
})
@@ -159,7 +158,11 @@ function warnDuplicateBlock(
)
}
function createBlock(node: ElementNode): SFCBlock {
function createBlock(
node: ElementNode,
source: string,
pad: SFCParseOptions['pad']
): SFCBlock {
const type = node.tag
const text = node.children[0] as TextNode
const attrs: Record<string, string | true> = {}
@@ -169,6 +172,9 @@ function createBlock(node: ElementNode): SFCBlock {
loc: text.loc,
attrs
}
if (node.tag !== 'template' && pad) {
block.content = padContent(source, block, pad) + block.content
}
node.props.forEach(p => {
if (p.type === NodeTypes.ATTRIBUTE) {
attrs[p.name] = p.value ? p.value.content || true : true
@@ -192,13 +198,14 @@ function createBlock(node: ElementNode): SFCBlock {
const splitRE = /\r?\n/g
const emptyRE = /^(?:\/\/)?\s*$/
const replaceRE = /./g
function generateSourceMap(
filename: string,
source: string,
generated: string,
sourceRoot: string,
pad?: 'line' | 'space'
pad?: SFCParseOptions['pad']
): RawSourceMap {
const map = new SourceMapGenerator({
file: filename.replace(/\\/g, '/'),
@@ -230,3 +237,18 @@ function generateSourceMap(
})
return JSON.parse(map.toString())
}
function padContent(
content: string,
block: SFCBlock,
pad: SFCParseOptions['pad']
): string {
content = content.slice(0, block.loc.start.offset)
if (pad === 'space') {
return content.replace(replaceRE, ' ')
} else {
const offset = content.split(splitRE).length
const padChar = block.type === 'script' && !block.lang ? '//\n' : '\n'
return Array(offset).join(padChar)
}
}