All files / compiler-ssr/src/transforms ssrVIf.ts

100% Statements 54/54
100% Branches 11/11
100% Functions 2/2
100% Lines 54/54

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 792x                     2x       2x     2x 2x 2x 2x       2x 30x 30x 30x 30x 30x 30x 30x 30x 30x 30x 30x   30x 30x 8x 8x 8x 8x 8x 8x 8x   2x 2x 2x 2x 8x   6x 6x 8x   30x 22x 22x 22x 22x 30x   38x 38x 38x 38x 38x 38x 38x 38x 34x   10x 38x 38x  
import {
  type BlockStatement,
  type IfBranchNode,
  type IfNode,
  type NodeTransform,
  NodeTypes,
  createBlockStatement,
  createCallExpression,
  createIfStatement,
  createStructuralDirectiveTransform,
  processIf,
} from '@vue/compiler-dom'
import {
  type SSRTransformContext,
  processChildrenAsStatement,
} from '../ssrCodegenTransform'
 
// Plugin for the first transform pass, which simply constructs the AST node
export const ssrTransformIf: NodeTransform = createStructuralDirectiveTransform(
  /^(if|else|else-if)$/,
  processIf,
)
 
// This is called during the 2nd transform pass to construct the SSR-specific
// codegen nodes.
export function ssrProcessIf(
  node: IfNode,
  context: SSRTransformContext,
  disableNestedFragments = false,
  disableComment = false,
): void {
  const [rootBranch] = node.branches
  const ifStatement = createIfStatement(
    rootBranch.condition!,
    processIfBranch(rootBranch, context, disableNestedFragments),
  )
  context.pushStatement(ifStatement)
 
  let currentIf = ifStatement
  for (let i = 1; i < node.branches.length; i++) {
    const branch = node.branches[i]
    const branchBlockStatement = processIfBranch(
      branch,
      context,
      disableNestedFragments,
    )
    if (branch.condition) {
      // else-if
      currentIf = currentIf.alternate = createIfStatement(
        branch.condition,
        branchBlockStatement,
      )
    } else {
      // else
      currentIf.alternate = branchBlockStatement
    }
  }
 
  if (!currentIf.alternate && !disableComment) {
    currentIf.alternate = createBlockStatement([
      createCallExpression(`_push`, ['`<!---->`']),
    ])
  }
}
 
function processIfBranch(
  branch: IfBranchNode,
  context: SSRTransformContext,
  disableNestedFragments = false,
): BlockStatement {
  const { children } = branch
  const needFragmentWrapper =
    !disableNestedFragments &&
    (children.length !== 1 || children[0].type !== NodeTypes.ELEMENT) &&
    // optimize away nested fragments when the only child is a ForNode
    !(children.length === 1 && children[0].type === NodeTypes.FOR)
  return processChildrenAsStatement(branch, context, needFragmentWrapper)
}