140 lines
5.7 KiB
JavaScript
140 lines
5.7 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.processIf = exports.transformIf = exports.isIfElementNode = void 0;
|
|
const types_1 = require("@babel/types");
|
|
const compiler_core_1 = require("@vue/compiler-core");
|
|
const ast_1 = require("../ast");
|
|
const transform_1 = require("../transform");
|
|
const transformExpression_1 = require("./transformExpression");
|
|
const utils_1 = require("./utils");
|
|
function isIfElementNode(node) {
|
|
return !!node.vIf;
|
|
}
|
|
exports.isIfElementNode = isIfElementNode;
|
|
exports.transformIf = (0, transform_1.createStructuralDirectiveTransform)(/^(if|else|else-if)$/, (node, dir, context) => {
|
|
return processIf(node, dir, context, (ifNode, branch, isRoot) => {
|
|
const { currentScope: parentScope, popScope } = context;
|
|
const ifOptions = {
|
|
name: dir.name,
|
|
};
|
|
branch.vIf = ifOptions;
|
|
const condition = dir.exp ? (0, ast_1.parseExpr)(dir.exp, context) : undefined;
|
|
const vIfScope = context.addVIfScope({
|
|
name: dir.name,
|
|
condition,
|
|
});
|
|
if (condition) {
|
|
if (!(0, utils_1.isStaticLiteral)(condition)) {
|
|
ifOptions.condition = (0, utils_1.rewriteExpression)(dir.exp, context, condition, parentScope).content;
|
|
}
|
|
else {
|
|
ifOptions.condition = dir.exp.content;
|
|
}
|
|
}
|
|
return () => {
|
|
if (isRoot) {
|
|
parentScope.properties.push((0, ast_1.createVIfSpreadElement)(vIfScope));
|
|
}
|
|
else {
|
|
const vIfSpreadElement = findVIfSpreadElement(parentScope);
|
|
if (!vIfSpreadElement) {
|
|
popScope();
|
|
return context.onError((0, compiler_core_1.createCompilerError)(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, node.loc));
|
|
}
|
|
let alternate = (0, ast_1.createObjectExpression)([]);
|
|
if (dir.name === 'else-if') {
|
|
alternate = (0, ast_1.createVIfConditionalExpression)(vIfScope);
|
|
}
|
|
else if (dir.name === 'else') {
|
|
alternate = (0, ast_1.createObjectExpression)(vIfScope.properties);
|
|
}
|
|
findVIfConditionalExpression(vIfSpreadElement.argument).alternate = alternate;
|
|
}
|
|
popScope();
|
|
};
|
|
});
|
|
});
|
|
function processIf(node, dir, context, processCodegen) {
|
|
if (dir.name !== 'else' &&
|
|
(!dir.exp || !dir.exp.content.trim())) {
|
|
const loc = dir.exp ? dir.exp.loc : node.loc;
|
|
context.onError((0, compiler_core_1.createCompilerError)(28 /* ErrorCodes.X_V_IF_NO_EXPRESSION */, dir.loc));
|
|
dir.exp = (0, compiler_core_1.createSimpleExpression)(`true`, false, loc);
|
|
}
|
|
if (context.prefixIdentifiers && dir.exp) {
|
|
// dir.exp can only be simple expression because vIf transform is applied
|
|
// before expression transform.
|
|
dir.exp = (0, transformExpression_1.processExpression)(dir.exp, context);
|
|
}
|
|
if (dir.name === 'if') {
|
|
const ifNode = {
|
|
type: 9 /* NodeTypes.IF */,
|
|
loc: node.loc,
|
|
branches: [node],
|
|
};
|
|
context.replaceNode(ifNode);
|
|
if (processCodegen) {
|
|
return processCodegen(ifNode, node, true);
|
|
}
|
|
}
|
|
else {
|
|
// locate the adjacent v-if
|
|
const siblings = context.parent.children;
|
|
let i = siblings.indexOf(node);
|
|
while (i-- >= -1) {
|
|
const sibling = siblings[i];
|
|
if (sibling && sibling.type === 3 /* NodeTypes.COMMENT */) {
|
|
context.removeNode(sibling);
|
|
continue;
|
|
}
|
|
if (sibling &&
|
|
sibling.type === 2 /* NodeTypes.TEXT */ &&
|
|
!sibling.content.trim().length) {
|
|
context.removeNode(sibling);
|
|
continue;
|
|
}
|
|
if (sibling && sibling.type === 9 /* NodeTypes.IF */) {
|
|
// Check if v-else was followed by v-else-if
|
|
if (dir.name === 'else-if' &&
|
|
sibling.branches[sibling.branches.length - 1].vIf.condition === undefined) {
|
|
context.onError((0, compiler_core_1.createCompilerError)(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, node.loc));
|
|
}
|
|
// move the node to the if node's branches
|
|
context.removeNode();
|
|
sibling.branches.push(node);
|
|
const onExit = processCodegen &&
|
|
processCodegen(sibling, node, false);
|
|
// since the branch was removed, it will not be traversed.
|
|
// make sure to traverse here.
|
|
(0, transform_1.traverseNode)(node, context);
|
|
// call on exit
|
|
if (onExit)
|
|
onExit();
|
|
// make sure to reset currentNode after traversal to indicate this
|
|
// node has been removed.
|
|
context.currentNode = null;
|
|
}
|
|
else {
|
|
context.onError((0, compiler_core_1.createCompilerError)(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, node.loc));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
exports.processIf = processIf;
|
|
function findVIfSpreadElement({ properties }) {
|
|
const len = properties.length;
|
|
for (let i = len - 1; i >= 0; i--) {
|
|
const prop = properties[i];
|
|
if ((0, types_1.isSpreadElement)(prop)) {
|
|
return prop;
|
|
}
|
|
}
|
|
}
|
|
function findVIfConditionalExpression(vIfConditionalExpression) {
|
|
if ((0, types_1.isConditionalExpression)(vIfConditionalExpression.alternate)) {
|
|
return findVIfConditionalExpression(vIfConditionalExpression.alternate);
|
|
}
|
|
return vIfConditionalExpression;
|
|
}
|