diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap index 4ecd8c76a7e..0a55629ecfb 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap @@ -252,3 +252,68 @@ export function render(_ctx) { return n1 }" `; + +exports[`compiler: transform slot > with whitespace: 'preserve' > implicit default slot 1`] = ` +"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, template as _template } from 'vue'; +const t0 = _template(" Header ") +const t1 = _template(" ") +const t2 = _template("

") + +export function render(_ctx) { + const _component_Comp = _resolveComponent("Comp") + const n4 = _createComponentWithFallback(_component_Comp, null, { + "header": () => { + const n0 = t0() + return n0 + }, + "default": () => { + const n2 = t1() + const n3 = t2() + return [n2, n3] + } + }, true) + return n4 +}" +`; + +exports[`compiler: transform slot > with whitespace: 'preserve' > named default slot + implicit whitespace content 1`] = ` +"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, template as _template } from 'vue'; +const t0 = _template(" Header ") +const t1 = _template(" Default ") + +export function render(_ctx) { + const _component_Comp = _resolveComponent("Comp") + const n4 = _createComponentWithFallback(_component_Comp, null, { + "header": () => { + const n0 = t0() + return n0 + }, + "default": () => { + const n2 = t1() + return n2 + } + }, true) + return n4 +}" +`; + +exports[`compiler: transform slot > with whitespace: 'preserve' > should not generate whitespace only default slot 1`] = ` +"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, template as _template } from 'vue'; +const t0 = _template(" Header ") +const t1 = _template(" Footer ") + +export function render(_ctx) { + const _component_Comp = _resolveComponent("Comp") + const n4 = _createComponentWithFallback(_component_Comp, null, { + "header": () => { + const n0 = t0() + return n0 + }, + "footer": () => { + const n2 = t1() + return n2 + } + }, true) + return n4 +}" +`; diff --git a/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts b/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts index 84ddb2e5d04..a066c7c9af5 100644 --- a/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts @@ -498,4 +498,60 @@ describe('compiler: transform slot', () => { }) }) }) + + describe(`with whitespace: 'preserve'`, () => { + test('named default slot + implicit whitespace content', () => { + const source = ` + + + + + ` + const { code } = compileWithSlots(source, { + whitespace: 'preserve', + }) + + expect( + `Extraneous children found when component already has explicitly named default slot.`, + ).not.toHaveBeenWarned() + expect(code).toMatchSnapshot() + }) + + test('implicit default slot', () => { + const source = ` + + +

+ + ` + const { code } = compileWithSlots(source, { + whitespace: 'preserve', + }) + + expect( + `Extraneous children found when component already has explicitly named default slot.`, + ).not.toHaveBeenWarned() + expect(code).toMatchSnapshot() + }) + + test('should not generate whitespace only default slot', () => { + const source = ` + + + + + ` + const { code, ir } = compileWithSlots(source, { + whitespace: 'preserve', + }) + + const slots = (ir.block.dynamic.children[0].operation as any).slots[0] + .slots + // should be: header, footer (no default) + expect(Object.keys(slots).length).toBe(2) + expect(!!slots['default']).toBe(false) + + expect(code).toMatchSnapshot() + }) + }) }) diff --git a/packages/compiler-vapor/src/transforms/vSlot.ts b/packages/compiler-vapor/src/transforms/vSlot.ts index d1bf1c6b05f..a375b79a94e 100644 --- a/packages/compiler-vapor/src/transforms/vSlot.ts +++ b/packages/compiler-vapor/src/transforms/vSlot.ts @@ -66,11 +66,19 @@ function transformComponentSlot( ) { const { children } = node const arg = dir && dir.arg - const nonSlotTemplateChildren = children.filter( - n => - isNonWhitespaceContent(node) && - !(n.type === NodeTypes.ELEMENT && n.props.some(isVSlot)), - ) + + // whitespace: 'preserve' + let indexes: number[] = [] + const nonSlotTemplateChildren = children.filter((n, i) => { + if (isNonWhitespaceContent(n)) { + return !(n.type === NodeTypes.ELEMENT && n.props.some(isVSlot)) + } else { + indexes.push(i) + } + }) + if (!nonSlotTemplateChildren.length) { + indexes.forEach(i => children.splice(i, 1)) + } const [block, onExit] = createSlotBlock(node, dir, context)