182 lines
7.4 KiB
JavaScript
182 lines
7.4 KiB
JavaScript
"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);
|
||
}
|