test(compiler): transformIf

This commit is contained in:
Evan You
2019-09-19 15:41:17 -04:00
parent 81fd694dd7
commit 2b4f06b24c
5 changed files with 371 additions and 26 deletions

View File

@@ -20,16 +20,23 @@ export const transformIf = createDirectiveTransform(
} else {
// locate the adjacent v-if
const siblings = context.parent.children
let i = context.childIndex
while (i--) {
const comments = []
let i = siblings.indexOf(node)
while (i-- >= -1) {
const sibling = siblings[i]
if (sibling.type === NodeTypes.COMMENT) {
if (__DEV__ && sibling && sibling.type === NodeTypes.COMMENT) {
context.removeNode(sibling)
comments.unshift(sibling)
continue
}
if (sibling.type === NodeTypes.IF) {
if (sibling && sibling.type === NodeTypes.IF) {
// move the node to the if node's branches
context.removeNode()
sibling.branches.push(createIfBranch(node, dir))
const branch = createIfBranch(node, dir)
if (__DEV__ && comments.length) {
branch.children = [...comments, ...branch.children]
}
sibling.branches.push(branch)
} else {
context.onError(
createCompilerError(

View File

@@ -186,6 +186,10 @@ function pushNode(
nodes: ChildNode[],
node: ChildNode
): void {
// ignore comments in production
if (!__DEV__ && node.type === NodeTypes.COMMENT) {
return
}
if (context.ignoreSpaces && node.type === NodeTypes.TEXT && node.isEmpty) {
return
}

View File

@@ -26,9 +26,10 @@ export interface TransformContext extends Required<TransformOptions> {
parent: ParentNode
ancestors: ParentNode[]
childIndex: number
currentNode: ChildNode | null
replaceNode(node: ChildNode): void
removeNode(): void
nodeRemoved: boolean
removeNode(node?: ChildNode): void
onNodeRemoved: () => void
}
export function transform(root: RootNode, options: TransformOptions) {
@@ -48,17 +49,37 @@ function createTransformContext(
parent: root,
ancestors: [],
childIndex: 0,
currentNode: null,
replaceNode(node) {
if (__DEV__ && context.nodeRemoved) {
throw new Error(`node being replaced is already removed`)
if (__DEV__ && !context.currentNode) {
throw new Error(`node being replaced is already removed.`)
}
context.parent.children[context.childIndex] = node
context.parent.children[context.childIndex] = context.currentNode = node
},
removeNode() {
context.parent.children.splice(context.childIndex, 1)
context.nodeRemoved = true
removeNode(node) {
const list = context.parent.children
const removalIndex = node
? list.indexOf(node)
: context.currentNode
? context.childIndex
: -1
if (__DEV__ && removalIndex < 0) {
throw new Error(`node being removed is not a child of current parent`)
}
if (!node || node === context.currentNode) {
// current node removed
context.currentNode = null
context.onNodeRemoved()
} else {
// sibling node removed
if (context.childIndex > removalIndex) {
context.childIndex--
context.onNodeRemoved()
}
}
context.parent.children.splice(removalIndex, 1)
},
nodeRemoved: false
onNodeRemoved: () => {}
}
return context
}
@@ -69,14 +90,16 @@ function traverseChildren(
ancestors: ParentNode[]
) {
ancestors = ancestors.concat(parent)
for (let i = 0; i < parent.children.length; i++) {
let i = 0
const nodeRemoved = () => {
i--
}
for (; i < parent.children.length; i++) {
context.parent = parent
context.ancestors = ancestors
context.childIndex = i
traverseNode(parent.children[i], context, ancestors)
if (context.nodeRemoved) {
i--
}
context.onNodeRemoved = nodeRemoved
traverseNode((context.currentNode = parent.children[i]), context, ancestors)
}
}
@@ -89,13 +112,12 @@ function traverseNode(
const transforms = context.transforms
for (let i = 0; i < transforms.length; i++) {
const plugin = transforms[i]
context.nodeRemoved = false
plugin(node, context)
if (context.nodeRemoved) {
if (!context.currentNode) {
return
} else {
// node may have been replaced
node = context.parent.children[context.childIndex]
node = context.currentNode
}
}