uni-ticket-system/node_modules/@dcloudio/uni-mp-compiler/dist/transforms/transformClass.js
2023-12-05 10:11:10 +08:00

182 lines
7.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createVirtualHostClass = exports.rewriteClass = exports.findStaticClassIndex = exports.isClassBinding = void 0;
const types_1 = require("@babel/types");
const compiler_core_1 = require("@vue/compiler-core");
const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
const ast_1 = require("../ast");
const codegen_1 = require("../codegen");
const runtimeHelpers_1 = require("../runtimeHelpers");
const utils_1 = require("./utils");
function isClassBinding({ arg }) {
return (arg && arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && arg.content === 'class');
}
exports.isClassBinding = isClassBinding;
function findStaticClassIndex(props) {
return props.findIndex((prop) => prop.name === 'class');
}
exports.findStaticClassIndex = findStaticClassIndex;
function rewriteClass(index, classBindingProp, props, virtualHost, context) {
const expr = classBindingProp.exp
? (0, ast_1.parseExpr)(classBindingProp.exp, context)
: undefined;
let classBindingExpr;
if (expr) {
classBindingExpr = expr;
if ((0, types_1.isObjectExpression)(expr)) {
classBindingExpr = createClassBindingByObjectExpression(rewriteClassObjectExpression(expr, classBindingProp.loc, context));
}
else if ((0, types_1.isArrayExpression)(expr)) {
classBindingExpr = createClassBindingByArrayExpression(rewriteClassArrayExpression(expr, context));
}
else {
classBindingExpr = (0, ast_1.parseExpr)(rewriteClassExpression(classBindingProp.exp, context).content, context);
}
}
else if (virtualHost) {
classBindingExpr = (0, types_1.arrayExpression)([]);
}
else {
return;
}
const staticClassPropIndex = findStaticClassIndex(props);
if (staticClassPropIndex > -1) {
const staticClass = props[staticClassPropIndex].value
.content;
if (staticClass) {
if (!(0, types_1.isArrayExpression)(classBindingExpr)) {
classBindingExpr = (0, types_1.arrayExpression)([classBindingExpr]);
}
const staticClassLiterals = parseStaticClass(staticClass);
if (index > staticClassPropIndex) {
classBindingExpr.elements.unshift(...staticClassLiterals);
}
else {
classBindingExpr.elements.push(...staticClassLiterals);
}
}
}
if (virtualHost) {
if (!(0, types_1.isArrayExpression)(classBindingExpr)) {
classBindingExpr = (0, types_1.arrayExpression)([classBindingExpr]);
}
classBindingExpr.elements.push((0, types_1.identifier)(utils_1.VIRTUAL_HOST_CLASS));
}
if (!context.miniProgram.class.array) {
classBindingExpr = parseClassBindingArrayExpr(classBindingExpr);
}
classBindingProp.exp = (0, compiler_core_1.createSimpleExpression)((0, codegen_1.genBabelExpr)(classBindingExpr));
}
exports.rewriteClass = rewriteClass;
function createVirtualHostClass(props, context) {
const classBindingProp = (0, uni_cli_shared_1.createBindDirectiveNode)('class', '');
delete classBindingProp.exp;
rewriteClass(0, classBindingProp, props, true, context);
return classBindingProp;
}
exports.createVirtualHostClass = createVirtualHostClass;
/**
* 目前 mp-toutiao, mp-alipay, mp-lark 不支持数组绑定class故统一转换为字符串相加
* @param classBindingExpr
* @returns
*/
function parseClassBindingArrayExpr(classBindingExpr) {
if (!(0, types_1.isArrayExpression)(classBindingExpr)) {
return classBindingExpr;
}
let binaryExpr;
classBindingExpr.elements.forEach((expr) => {
if ((0, types_1.isArrayExpression)(expr)) {
expr = parseClassBindingArrayExpr(expr);
}
if (!binaryExpr) {
binaryExpr = (0, types_1.parenthesizedExpression)(expr);
}
else {
binaryExpr = (0, types_1.binaryExpression)('+', (0, types_1.binaryExpression)('+', binaryExpr, (0, types_1.stringLiteral)(' ')), expr);
}
});
return binaryExpr;
}
function parseStaticClass(staticClass) {
// 已经在 parse 阶段格式化了多余空格等
return staticClass.split(' ').map((clazz) => (0, types_1.stringLiteral)(clazz));
}
function rewriteClassExpression(expr, context) {
return (0, utils_1.rewriteExpression)((0, compiler_core_1.createCompoundExpression)([
context.helperString(runtimeHelpers_1.NORMALIZE_CLASS) + '(',
expr,
')',
]), context);
}
function rewriteClassArrayExpression(expr, context) {
expr.elements.forEach((prop, index) => {
if (!(0, types_1.isStringLiteral)(prop)) {
const code = (0, codegen_1.genBabelExpr)((0, types_1.arrayExpression)([(0, types_1.isSpreadElement)(prop) ? prop.argument : prop]));
expr.elements[index] = (0, types_1.identifier)(rewriteClassExpression((0, compiler_core_1.createSimpleExpression)(code.slice(1, -1), false), context).content);
}
});
return expr;
}
function rewriteClassObjectExpression(expr, loc, context) {
expr.properties.forEach((prop, index) => {
if ((0, types_1.isSpreadElement)(prop)) {
// <view :class="{...obj}"/>
// <view class="{{[a]}}"/>
const newExpr = (0, utils_1.rewriteSpreadElement)(runtimeHelpers_1.NORMALIZE_CLASS, prop, loc, context);
if (newExpr) {
expr.properties[index] = (0, types_1.objectProperty)(newExpr, (0, types_1.booleanLiteral)(true), true);
}
}
else if ((0, types_1.isObjectProperty)(prop)) {
const { key, value, computed } = prop;
if (computed) {
// {[handle(computedKey)]:1} => {[a]:1}
prop.key = (0, utils_1.parseExprWithRewrite)((0, codegen_1.genBabelExpr)(key), loc, context, key);
}
if ((0, utils_1.isStaticLiteral)(value)) {
return;
}
else {
const newExpr = (0, utils_1.parseExprWithRewriteClass)((0, codegen_1.genBabelExpr)(value), loc, context, value);
if (newExpr) {
prop.value = newExpr;
}
}
}
});
return expr;
}
function createClassBindingByArrayExpression(expr) {
const elements = [];
expr.elements.forEach((prop) => {
if ((0, types_1.isStringLiteral)(prop) || (0, types_1.isIdentifier)(prop)) {
elements.push(prop);
}
});
return (0, types_1.arrayExpression)(elements);
}
function createClassBindingByObjectExpression(expr) {
const elements = [];
expr.properties.forEach((prop) => {
if ((0, types_1.isObjectProperty)(prop)) {
const { value } = prop;
if ((0, ast_1.isUndefined)(value) || (0, types_1.isPrivateName)(prop.key)) {
// remove {a:undefined}
return;
}
if ((0, types_1.isLiteral)(value)) {
// {a:true,b:1,c:0} => ['a','b']
if ((0, ast_1.isTrueExpr)(value)) {
elements.push(prop.computed
? prop.key
: (0, ast_1.parseStringLiteral)(prop.key));
}
return;
}
elements.push((0, types_1.logicalExpression)('&&', value, prop.computed ? prop.key : (0, ast_1.parseStringLiteral)(prop.key)));
}
});
return (0, types_1.arrayExpression)(elements);
}