|
|
@@ -5,8 +5,8 @@ import {
|
|
|
type IfBranchNode,
|
|
|
NodeTypes,
|
|
|
type SimpleExpressionNode,
|
|
|
+ type SkipNode,
|
|
|
type SlotsExpression,
|
|
|
- type SourceLocation,
|
|
|
type TemplateChildNode,
|
|
|
createConditionalExpression,
|
|
|
createSimpleExpression,
|
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
} from '../transform'
|
|
|
import {
|
|
|
ErrorCodes,
|
|
|
+ buildSlots,
|
|
|
createCompilerError,
|
|
|
findDir,
|
|
|
findProp,
|
|
|
@@ -27,61 +28,17 @@ import {
|
|
|
} 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),
|
|
|
)
|
|
|
}
|
|
|
})
|
|
|
@@ -92,7 +49,7 @@ export function processSkip(
|
|
|
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)) {
|
|
|
@@ -117,5 +74,58 @@ export function processSkip(
|
|
|
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)
|
|
|
}
|