diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap index 608e4bac510..232aba02a64 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap @@ -308,3 +308,17 @@ export function render(_ctx) { return n0 }" `; + +exports[`compiler: v-if > v-on with v-if 1`] = ` +"import { setDynamicEvents as _setDynamicEvents, renderEffect as _renderEffect, createIf as _createIf, template as _template } from 'vue'; +const t0 = _template("", true) + +export function render(_ctx) { + const n0 = _createIf(() => (true), () => { + const n2 = t0() + _renderEffect(() => _setDynamicEvents(n2, { click: _ctx.clickEvent })) + return n2 + }, null, true) + return n0 +}" +`; diff --git a/packages/compiler-vapor/__tests__/transforms/vIf.spec.ts b/packages/compiler-vapor/__tests__/transforms/vIf.spec.ts index 728b3f9c41f..482794356ed 100644 --- a/packages/compiler-vapor/__tests__/transforms/vIf.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vIf.spec.ts @@ -11,7 +11,7 @@ import { transformVOnce, transformVText, } from '../../src' -import { NodeTypes } from '@vue/compiler-dom' +import { ErrorCodes, NodeTypes, type RootNode } from '@vue/compiler-dom' const compileWithVIf = makeCompile({ nodeTransforms: [ @@ -380,7 +380,181 @@ describe('compiler: v-if', () => { ]) }) - describe.todo('errors') - describe.todo('codegen') - test.todo('v-on with v-if') + test('v-on with v-if', () => { + const { code, ir } = compileWithVIf( + ``, + ) + expect(code).toMatchSnapshot() + expect([...ir.template.keys()]).toEqual(['']) + + expect(ir.block.returns).toEqual([0]) + expect(ir.block.dynamic.children[0].operation).toMatchObject({ + type: IRNodeTypes.IF, + condition: { + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'true', + isStatic: false, + }, + positive: { + type: IRNodeTypes.BLOCK, + dynamic: { + children: [{ template: 0 }], + }, + }, + }) + }) + + describe('errors', () => { + test('error on v-else missing adjacent v-if', () => { + const onError = vi.fn() + + { + const { ir } = compileWithVIf(`
`, { onError }) + expect(onError.mock.calls[0]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: ir.node.loc, + }, + ]) + } + + { + const { ir } = compileWithVIf(``, { + onError, + }) + expect(onError.mock.calls[1]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: (ir.block.node as RootNode).children[1].loc, + }, + ]) + } + + { + const { ir } = compileWithVIf(`foo`, { onError }) + expect(onError.mock.calls[2]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: (ir.block.node as RootNode).children[2].loc, + }, + ]) + } + + { + const { ir } = compileWithVIf(`foo`, { + onError, + }) + expect(onError.mock.calls[3]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: (ir.block.node as RootNode).children[2].loc, + }, + ]) + } + + // Non-breaking space + { + const { ir } = compileWithVIf(`\u00a0`, { + onError, + }) + expect(onError.mock.calls[4]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: (ir.block.node as RootNode).children[2].loc, + }, + ]) + } + }) + + test('error on v-else-if missing adjacent v-if or v-else-if', () => { + const onError = vi.fn() + { + const { ir } = compileWithVIf(``, { + onError, + }) + expect(onError.mock.calls[0]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: ir.node.loc, + }, + ]) + } + { + const { ir } = compileWithVIf(``, { + onError, + }) + expect(onError.mock.calls[1]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: (ir.block.node as RootNode).children[1].loc, + }, + ]) + } + { + const { ir } = compileWithVIf(`foo`, { + onError, + }) + expect(onError.mock.calls[2]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: (ir.block.node as RootNode).children[2].loc, + }, + ]) + } + { + const { ir } = compileWithVIf( + `foo`, + { onError }, + ) + expect(onError.mock.calls[3]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: (ir.block.node as RootNode).children[2].loc, + }, + ]) + } + { + // Non-breaking space + const { ir } = compileWithVIf( + `\u00a0`, + { onError }, + ) + expect(onError.mock.calls[4]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: (ir.block.node as RootNode).children[2].loc, + }, + ]) + } + + { + const { ir } = compileWithVIf( + ``, + { onError }, + ) + expect(onError.mock.calls[5]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: (ir.block.node as RootNode).children[2].loc, + }, + ]) + } + }) + + test('error on adjacent v-else', () => { + const onError = vi.fn() + + const { ir } = compileWithVIf( + ``, + { onError }, + ) + + expect(onError.mock.calls[0]).toMatchObject([ + { + code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, + loc: (ir.block.node as RootNode).children[2].loc, + }, + ]) + }) + }) }) diff --git a/packages/compiler-vapor/src/transforms/transformComment.ts b/packages/compiler-vapor/src/transforms/transformComment.ts index f85498febce..3850320bf2a 100644 --- a/packages/compiler-vapor/src/transforms/transformComment.ts +++ b/packages/compiler-vapor/src/transforms/transformComment.ts @@ -3,6 +3,7 @@ import { type ElementNode, NodeTypes, type TemplateChildNode, + isCommentOrWhitespace, } from '@vue/compiler-dom' import type { NodeTransform, TransformContext } from '../transform' import { DynamicFlag } from '../ir' @@ -31,7 +32,7 @@ export function getSiblingIf( let i = siblings.indexOf(context.node) while (reverse ? --i >= 0 : ++i < siblings.length) { sibling = siblings[i] - if (!isCommentLike(sibling)) { + if (!isCommentOrWhitespace(sibling)) { break } } @@ -48,10 +49,3 @@ export function getSiblingIf( return sibling } } - -function isCommentLike(node: TemplateChildNode) { - return ( - node.type === NodeTypes.COMMENT || - (node.type === NodeTypes.TEXT && !node.content.trim().length) - ) -}