Skip to content

Commit 2dc177f

Browse files
sandersnyyx990803
authored andcommitted
SFC parseComponent pads complete content with spaces (#5059)
* SFC parseComponent pads content with spaces when `{ pad: true }` is provided. That is, all content is converted to spaces. Previously, each line was truncated to "//". The new padding method works better with character-oriented tools that calculate positions by distance from the beginning of the file instead of by line number. * Made parseComponent's pad support "line" | "space" Also still supports true for backward compatibility. True is the same as "line".
1 parent eb58694 commit 2dc177f

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

Diff for: packages/vue-template-compiler/README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,9 @@ Parse a SFC (single-file component, or `*.vue` file) into a descriptor (refer to
8585
8686
#### Options
8787
88-
- `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.
88+
#### `pad`
89+
90+
`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.
91+
92+
- 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.
93+
- 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.

Diff for: src/sfc/parser.js

+12-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { parseHTML } from 'compiler/parser/html-parser'
55
import { makeMap } from 'shared/util'
66

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

1011
type Attribute = {
@@ -86,20 +87,24 @@ export function parseComponent (
8687
// pad content so that linters and pre-processors can output correct
8788
// line numbers in errors and warnings
8889
if (currentBlock.type !== 'template' && options.pad) {
89-
text = padContent(currentBlock) + text
90+
text = padContent(currentBlock, options.pad) + text
9091
}
9192
currentBlock.content = text
9293
currentBlock = null
9394
}
9495
depth--
9596
}
9697

97-
function padContent (block: SFCBlock | SFCCustomBlock) {
98-
const offset = content.slice(0, block.start).split(splitRE).length
99-
const padChar = block.type === 'script' && !block.lang
100-
? '//\n'
101-
: '\n'
102-
return Array(offset).join(padChar)
98+
function padContent (block: SFCBlock | SFCCustomBlock, pad: true | "line" | "space") {
99+
if (pad === 'space') {
100+
return content.slice(0, block.start).replace(replaceRE, ' ')
101+
} else {
102+
const offset = content.slice(0, block.start).split(splitRE).length
103+
const padChar = block.type === 'script' && !block.lang
104+
? '//\n'
105+
: '\n'
106+
return Array(offset).join(padChar)
107+
}
103108
}
104109

105110
parseHTML(content, {

Diff for: test/unit/modules/sfc/sfc-parser.spec.js

+21-4
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ describe('Single File Component parser', () => {
5656
})
5757

5858
it('pad content', () => {
59-
const res = parseComponent(`
59+
const content = `
6060
<template>
6161
<div></div>
6262
</template>
@@ -66,9 +66,26 @@ describe('Single File Component parser', () => {
6666
<style>
6767
h1 { color: red }
6868
</style>
69-
`.trim(), { pad: true })
70-
expect(res.script.content).toBe(Array(3 + 1).join('//\n') + '\nexport default {}\n')
71-
expect(res.styles[0].content).toBe(Array(6 + 1).join('\n') + '\nh1 { color: red }\n')
69+
`
70+
const padDefault = parseComponent(content.trim(), { pad: true })
71+
const padLine = parseComponent(content.trim(), { pad: 'line' })
72+
const padSpace = parseComponent(content.trim(), { pad: 'space' })
73+
74+
expect(padDefault.script.content).toBe(Array(3 + 1).join('//\n') + '\nexport default {}\n')
75+
expect(padDefault.styles[0].content).toBe(Array(6 + 1).join('\n') + '\nh1 { color: red }\n')
76+
expect(padLine.script.content).toBe(Array(3 + 1).join('//\n') + '\nexport default {}\n')
77+
expect(padLine.styles[0].content).toBe(Array(6 + 1).join('\n') + '\nh1 { color: red }\n')
78+
expect(padSpace.script.content).toBe(`<template>
79+
<div></div>
80+
</template>
81+
<script>`.replace(/./g, ' ') + '\nexport default {}\n')
82+
expect(padSpace.styles[0].content).toBe(`<template>
83+
<div></div>
84+
</template>
85+
<script>
86+
export default {}
87+
</script>
88+
<style>`.replace(/./g, ' ') + '\nh1 { color: red }\n')
7289
})
7390

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

0 commit comments

Comments
 (0)