type IfBranchNode,
NodeTypes,
type SimpleExpressionNode,
+ type SkipNode,
type SlotsExpression,
- type SourceLocation,
type TemplateChildNode,
createConditionalExpression,
createSimpleExpression,
} from '../transform'
import {
ErrorCodes,
+ buildSlots,
createCompilerError,
findDir,
findProp,
} from '@vue/compiler-core'
import { createCodegenNodeForBranch } from './vIf'
import { validateBrowserExpression } from '../validateExpression'
+import { cloneLoc } from '../parser'
export const transformSkip: NodeTransform = createStructuralDirectiveTransform(
'skip',
(node, dir, context) => {
- return processSkip(node, dir, context, loc => {
+ return processSkip(node, dir, context, skipNode => {
return () => {
- let children: TemplateChildNode[] = []
- // for components, extract default slot without props
- // if not found, throw an error
- if (node.tagType === ElementTypes.COMPONENT) {
- const codegenNode = node.codegenNode!
- if (codegenNode.type === NodeTypes.VNODE_CALL) {
- const genChildren = codegenNode.children! as SlotsExpression
- if (genChildren.type === NodeTypes.JS_OBJECT_EXPRESSION) {
- const prop = genChildren.properties.find(
- p =>
- p.type === NodeTypes.JS_PROPERTY &&
- p.key.type === NodeTypes.SIMPLE_EXPRESSION &&
- p.key.content === 'default' &&
- p.value.params === undefined,
- )
- if (prop) {
- children = prop.value.returns as TemplateChildNode[]
- } else {
- context.onError(
- createCompilerError(ErrorCodes.X_V_SKIP_UNEXPECTED_SLOT, loc),
- )
- }
- }
- }
- }
- // for plain elements, take all children
- else {
- children = node.children
- }
- const consequent: IfBranchNode = {
- type: NodeTypes.IF_BRANCH,
- loc: node.loc,
- condition: undefined,
- children,
- userKey: findProp(node, `key`),
- }
-
- const alternate: IfBranchNode = {
- type: NodeTypes.IF_BRANCH,
- loc: node.loc,
- condition: undefined,
- children: [node],
- userKey: findProp(node, `key`),
- }
-
- node.codegenNode = createConditionalExpression(
+ skipNode.codegenNode = createConditionalExpression(
dir.exp!,
- createCodegenNodeForBranch(consequent, 0, context),
- createCodegenNodeForBranch(alternate, 1, context),
+ createCodegenNodeForBranch(skipNode.consequent, 0, context),
+ createCodegenNodeForBranch(skipNode.alternate, 1, context),
)
}
})
node: ElementNode,
dir: DirectiveNode,
context: TransformContext,
- processCodegen?: (loc: SourceLocation) => () => void,
+ processCodegen?: (skipNode: SkipNode) => () => void,
): (() => void) | undefined {
const loc = dir.exp ? dir.exp.loc : node.loc
if (isTemplateNode(node) || isSlotOutlet(node)) {
validateBrowserExpression(dir.exp as SimpleExpressionNode, context)
}
- if (processCodegen) return processCodegen(loc)
+ let children: TemplateChildNode[] = []
+ // for components, extract default slot without props
+ // if not found, throw an error
+ if (node.tagType === ElementTypes.COMPONENT) {
+ const { slots } = buildSlots(node, context)
+ const genChildren = slots as SlotsExpression
+ if (genChildren.type === NodeTypes.JS_OBJECT_EXPRESSION) {
+ const prop = genChildren.properties.find(
+ p =>
+ p.type === NodeTypes.JS_PROPERTY &&
+ p.key.type === NodeTypes.SIMPLE_EXPRESSION &&
+ p.key.content === 'default' &&
+ p.value.params === undefined,
+ )
+ if (prop) {
+ children = prop.value.returns as TemplateChildNode[]
+ } else {
+ context.onError(
+ createCompilerError(ErrorCodes.X_V_SKIP_UNEXPECTED_SLOT, loc),
+ )
+ }
+ }
+ }
+ // for plain elements, take all children
+ else {
+ children = node.children
+ }
+
+ const consequent: IfBranchNode = {
+ type: NodeTypes.IF_BRANCH,
+ loc: node.loc,
+ condition: undefined,
+ children,
+ userKey: findProp(node, `key`),
+ }
+
+ const alternate: IfBranchNode = {
+ type: NodeTypes.IF_BRANCH,
+ loc: node.loc,
+ condition: undefined,
+ children: [node],
+ userKey: findProp(node, `key`),
+ }
+
+ const skipNode: SkipNode = {
+ type: NodeTypes.SKIP,
+ loc: cloneLoc(node.loc),
+ test: dir.exp,
+ consequent,
+ alternate,
+ newline: true,
+ }
+ context.replaceNode(skipNode)
+ if (processCodegen) return processCodegen(skipNode)
}
import {
- type ComponentNode,
- type DirectiveNode,
- type IfBranchNode,
type NodeTransform,
- NodeTypes,
- type PlainElementNode,
+ type SkipNode,
createIfStatement,
createStructuralDirectiveTransform,
processSkip,
createStructuralDirectiveTransform('skip', processSkip)
export function ssrProcessSkip(
- node: PlainElementNode | ComponentNode,
- dir: DirectiveNode,
+ node: SkipNode,
context: SSRTransformContext,
): void {
- node.props = node.props.filter(x => x.name !== 'skip')
- const consequent: IfBranchNode = {
- type: NodeTypes.IF_BRANCH,
- loc: node.loc,
- condition: undefined,
- children: node.children,
- }
-
- const alternate: IfBranchNode = {
- type: NodeTypes.IF_BRANCH,
- loc: node.loc,
- condition: undefined,
- children: [node],
- }
-
- const ifNode = createIfStatement(
- dir.exp!,
- processIfBranch(consequent, context),
- processIfBranch(alternate, context),
+ const ifStatement = createIfStatement(
+ node.test,
+ processIfBranch(node.consequent, context),
+ processIfBranch(node.alternate, context),
)
-
- context.pushStatement(ifNode)
+ context.pushStatement(ifStatement)
}