Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SFC parseComponent pads complete content with spaces #5059

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/vue-template-compiler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,9 @@ Parse a SFC (single-file component, or `*.vue` file) into a descriptor (refer to

#### Options

- `pad`: with `{ pad: true }`, the extracted content for each block will be padded with newlines to ensure that the line numbers align with the original file. This is useful when you are piping the extracted content into other pre-processors, as you will get correct line numbers if there are any syntax errors.
#### `pad`

`pad` is useful when you are piping the extracted content into other pre-processors, as you will get correct line numbers or character indices if there are any syntax errors.

- with `{ pad: "line" }`, the extracted content for each block will be prefixed with one newline for each line in the leading content from the original file to ensure that the line numbers align with the original file.
- with `{ pad: "space" }`, the extracted content for each block will be prefixed with one space for each character in the leading content from the original file to ensure that the character count remains the same as the original file.
19 changes: 12 additions & 7 deletions src/sfc/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { parseHTML } from 'compiler/parser/html-parser'
import { makeMap } from 'shared/util'

const splitRE = /\r?\n/g
const replaceRE = /./g
const isSpecialTag = makeMap('script,style,template', true)

type Attribute = {
Expand Down Expand Up @@ -86,20 +87,24 @@ export function parseComponent (
// pad content so that linters and pre-processors can output correct
// line numbers in errors and warnings
if (currentBlock.type !== 'template' && options.pad) {
text = padContent(currentBlock) + text
text = padContent(currentBlock, options.pad) + text
}
currentBlock.content = text
currentBlock = null
}
depth--
}

function padContent (block: SFCBlock | SFCCustomBlock) {
const offset = content.slice(0, block.start).split(splitRE).length
const padChar = block.type === 'script' && !block.lang
? '//\n'
: '\n'
return Array(offset).join(padChar)
function padContent (block: SFCBlock | SFCCustomBlock, pad: true | "line" | "space") {
if (pad === 'space') {
return content.slice(0, block.start).replace(replaceRE, ' ')
} else {
const offset = content.slice(0, block.start).split(splitRE).length
const padChar = block.type === 'script' && !block.lang
? '//\n'
: '\n'
return Array(offset).join(padChar)
}
}

parseHTML(content, {
Expand Down
25 changes: 21 additions & 4 deletions test/unit/modules/sfc/sfc-parser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('Single File Component parser', () => {
})

it('pad content', () => {
const res = parseComponent(`
const content = `
<template>
<div></div>
</template>
Expand All @@ -66,9 +66,26 @@ describe('Single File Component parser', () => {
<style>
h1 { color: red }
</style>
`.trim(), { pad: true })
expect(res.script.content).toBe(Array(3 + 1).join('//\n') + '\nexport default {}\n')
expect(res.styles[0].content).toBe(Array(6 + 1).join('\n') + '\nh1 { color: red }\n')
`
const padDefault = parseComponent(content.trim(), { pad: true })
const padLine = parseComponent(content.trim(), { pad: 'line' })
const padSpace = parseComponent(content.trim(), { pad: 'space' })

expect(padDefault.script.content).toBe(Array(3 + 1).join('//\n') + '\nexport default {}\n')
expect(padDefault.styles[0].content).toBe(Array(6 + 1).join('\n') + '\nh1 { color: red }\n')
expect(padLine.script.content).toBe(Array(3 + 1).join('//\n') + '\nexport default {}\n')
expect(padLine.styles[0].content).toBe(Array(6 + 1).join('\n') + '\nh1 { color: red }\n')
expect(padSpace.script.content).toBe(`<template>
<div></div>
</template>
<script>`.replace(/./g, ' ') + '\nexport default {}\n')
expect(padSpace.styles[0].content).toBe(`<template>
<div></div>
</template>
<script>
export default {}
</script>
<style>`.replace(/./g, ' ') + '\nh1 { color: red }\n')
})

it('should handle template blocks with lang as special text', () => {
Expand Down