Repository: vuejs/vue
Pull request: feat(#7054): vue-template-compiler support switch deindent

Add feature for #7054

usage: `vue_template_compiler.parseComponent(vue, { deindent: false })`

deindent can be `true` or `false`, default is `true`

**What kind of change does this PR introduce?** (check at least one)

- [ ] Bugfix
- [x] Feature
- [ ] Code style update
- [ ] Refactor
- [ ] Build-related changes
- [ ] Other, please describe:

**Does this PR introduce a breaking change?** (check one)

- [ ] Yes
- [x] No

If yes, please describe the impact and migration path for existing applications:

**The PR fulfills these requirements:**

- [x] It's submitted to the `dev` branch for v2.x (or to a previous version branch), _not_ the `master` branch
- [x] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
- [x] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
- [x] New/updated tests are included

If adding a **new feature**, the PR's description includes:
- [x] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)


Changed files:
filename: src/sfc/parser.js
patch: @@ -83,7 +83,10 @@ export function parseComponent (
   function end (tag: string, start: number) {
     if (depth === 1 && currentBlock) {
       currentBlock.end = start
-      let text = deindent(content.slice(currentBlock.start, currentBlock.end))
+      let text = content.slice(currentBlock.start, currentBlock.end)
+      if (options.deindent !== false) {
+        text = deindent(text)
+      }
       // pad content so that linters and pre-processors can output correct
       // line numbers in errors and warnings
       if (currentBlock.type !== 'template' && options.pad) {

filename: test/unit/modules/sfc/sfc-parser.spec.js
patch: @@ -55,6 +55,33 @@ describe('Single File Component parser', () => {
     expect(res.template.content.trim()).toBe('<div><template v-if="ok">hi</template></div>')
   })
 
+  it('deindent content', () => {
+    const content = `
+      <template>
+        <div></div>
+      </template>
+      <script>
+        export default {}
+      </script>
+      <style>
+        h1 { color: red }
+      </style>
+    `
+    const deindentDefault = parseComponent(content.trim(), { pad: false })
+    const deindentEnabled = parseComponent(content.trim(), { pad: false, deindent: true })
+    const deindentDisabled = parseComponent(content.trim(), { pad: false, deindent: false })
+
+    expect(deindentDefault.template.content).toBe('\n<div></div>\n')
+    expect(deindentDefault.script.content).toBe('\nexport default {}\n')
+    expect(deindentDefault.styles[0].content).toBe('\nh1 { color: red }\n')
+    expect(deindentEnabled.template.content).toBe('\n<div></div>\n')
+    expect(deindentEnabled.script.content).toBe('\nexport default {}\n')
+    expect(deindentEnabled.styles[0].content).toBe('\nh1 { color: red }\n')
+    expect(deindentDisabled.template.content).toBe('\n        <div></div>\n      ')
+    expect(deindentDisabled.script.content).toBe('\n        export default {}\n      ')
+    expect(deindentDisabled.styles[0].content).toBe('\n        h1 { color: red }\n      ')
+  })
+
   it('pad content', () => {
     const content = `
       <template>