209 lines
7.4 KiB
JavaScript
209 lines
7.4 KiB
JavaScript
|
"use strict";
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.rewritePropsBinding = exports.isPropsBinding = exports.rewriteBinding = exports.transformComponent = void 0;
|
||
|
const shared_1 = require("@vue/shared");
|
||
|
const compiler_core_1 = require("@vue/compiler-core");
|
||
|
const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
|
||
|
const transform_1 = require("../transform");
|
||
|
const utils_1 = require("./utils");
|
||
|
const codegen_1 = require("../codegen");
|
||
|
const types_1 = require("@babel/types");
|
||
|
const runtimeHelpers_1 = require("../runtimeHelpers");
|
||
|
const ast_1 = require("../ast");
|
||
|
const vIf_1 = require("./vIf");
|
||
|
const transformComponent = (node, context) => {
|
||
|
if (!(0, uni_cli_shared_1.isUserComponent)(node, context)) {
|
||
|
return;
|
||
|
}
|
||
|
addComponentType(node, context);
|
||
|
addVueId(node, context);
|
||
|
processBooleanAttr(node);
|
||
|
return function postTransformComponent() {
|
||
|
context.vueIds.pop();
|
||
|
};
|
||
|
};
|
||
|
exports.transformComponent = transformComponent;
|
||
|
function addComponentType(node, context) {
|
||
|
if (!context.isMiniProgramComponent(node.tag)) {
|
||
|
return;
|
||
|
}
|
||
|
node.props.push((0, uni_cli_shared_1.createAttributeNode)(utils_1.ATTR_COM_TYPE, 'm'));
|
||
|
}
|
||
|
function addVueId(node, context) {
|
||
|
let { hashId, scopes, currentScope, currentVueId } = context;
|
||
|
if (!hashId) {
|
||
|
return;
|
||
|
}
|
||
|
let vueId = hashId + '-' + scopes.vueId++;
|
||
|
const indexs = [];
|
||
|
while (currentScope) {
|
||
|
if ((0, transform_1.isVForScope)(currentScope)) {
|
||
|
indexs.push(`+'-'+${currentScope.indexAlias}`);
|
||
|
}
|
||
|
currentScope = currentScope.parent;
|
||
|
}
|
||
|
const inFor = !!indexs.length;
|
||
|
if (inFor) {
|
||
|
vueId = `'${vueId}'` + indexs.reverse().join('');
|
||
|
}
|
||
|
context.vueIds.push(vueId);
|
||
|
let value = vueId;
|
||
|
if (currentVueId) {
|
||
|
const isParentDynamic = currentVueId.includes('+');
|
||
|
const isCurrentDynamic = vueId.includes('+');
|
||
|
if (isParentDynamic || isCurrentDynamic) {
|
||
|
value = `(${vueId})+','+(${isParentDynamic ? currentVueId : `'${currentVueId}'`})`;
|
||
|
}
|
||
|
else {
|
||
|
value = vueId + ',' + currentVueId;
|
||
|
}
|
||
|
}
|
||
|
if (value.includes('+')) {
|
||
|
return node.props.push((0, uni_cli_shared_1.createBindDirectiveNode)(utils_1.ATTR_VUE_ID, value));
|
||
|
}
|
||
|
return node.props.push((0, uni_cli_shared_1.createAttributeNode)(utils_1.ATTR_VUE_ID, value));
|
||
|
}
|
||
|
/**
|
||
|
* <uni-collapse accordion/> => <uni-collapse :accordion="true"/>
|
||
|
* 否则部分平台(快手)可能获取到的 accordion 是空字符串
|
||
|
* @param param0
|
||
|
*/
|
||
|
function processBooleanAttr({ props }) {
|
||
|
props.forEach((prop, index) => {
|
||
|
if (prop.type === 6 /* NodeTypes.ATTRIBUTE */ &&
|
||
|
typeof prop.value === 'undefined') {
|
||
|
props.splice(index, 1, (0, uni_cli_shared_1.createBindDirectiveNode)(prop.name, 'true'));
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
const builtInProps = [
|
||
|
// 'id',
|
||
|
'class',
|
||
|
'style',
|
||
|
utils_1.ATTR_VUE_ID,
|
||
|
utils_1.ATTR_VUE_PROPS,
|
||
|
utils_1.ATTR_VUE_SLOTS,
|
||
|
utils_1.ATTR_VUE_REF,
|
||
|
utils_1.ATTR_VUE_REF_IN_FOR,
|
||
|
utils_1.ATTR_COM_TYPE,
|
||
|
'eO',
|
||
|
'e-o',
|
||
|
'onVI',
|
||
|
'ref',
|
||
|
'slot',
|
||
|
'key',
|
||
|
'is',
|
||
|
];
|
||
|
function isComponentProp(name) {
|
||
|
if (builtInProps.includes(name)) {
|
||
|
return false;
|
||
|
}
|
||
|
if (name.startsWith('data-')) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
/**
|
||
|
* 重写组件 props 绑定
|
||
|
* @param node
|
||
|
* @param context
|
||
|
*/
|
||
|
function rewriteBinding({ tag, props }, context) {
|
||
|
const isMiniProgramComponent = context.isMiniProgramComponent(tag);
|
||
|
if (isMiniProgramComponent === 'plugin' ||
|
||
|
isMiniProgramComponent === 'dynamicLib') {
|
||
|
// 因无法介入插件类型组件内部实现,故保留原始属性
|
||
|
return;
|
||
|
}
|
||
|
const createObjectProperty = isMiniProgramComponent
|
||
|
? (name, value) => (0, types_1.objectProperty)((0, types_1.identifier)((0, shared_1.camelize)(name)), value)
|
||
|
: (name, value) => {
|
||
|
const computed = !(0, compiler_core_1.isSimpleIdentifier)(name);
|
||
|
return (0, types_1.objectProperty)(computed ? (0, types_1.stringLiteral)(name) : (0, types_1.identifier)(name), value, computed);
|
||
|
};
|
||
|
const properties = [];
|
||
|
for (let i = 0; i < props.length; i++) {
|
||
|
const prop = props[i];
|
||
|
let isIdProp = false;
|
||
|
if ((0, uni_cli_shared_1.isAttributeNode)(prop)) {
|
||
|
const { name } = prop;
|
||
|
isIdProp = name === 'id';
|
||
|
if (!isComponentProp(name)) {
|
||
|
continue;
|
||
|
}
|
||
|
properties.push(createObjectProperty(name, (0, types_1.stringLiteral)(prop.value?.content || '')));
|
||
|
}
|
||
|
else if ((0, uni_cli_shared_1.isDirectiveNode)(prop)) {
|
||
|
if (prop.name !== 'bind') {
|
||
|
continue;
|
||
|
}
|
||
|
const { arg, exp } = prop;
|
||
|
if (!exp) {
|
||
|
continue;
|
||
|
}
|
||
|
if (!arg) {
|
||
|
const spreadElement = createVBindSpreadElement(prop, context);
|
||
|
if (spreadElement) {
|
||
|
properties.push(spreadElement);
|
||
|
}
|
||
|
}
|
||
|
else if ((0, compiler_core_1.isStaticExp)(arg)) {
|
||
|
isIdProp = arg.content === 'id';
|
||
|
if (!isComponentProp(arg.content)) {
|
||
|
continue;
|
||
|
}
|
||
|
// :name="name"
|
||
|
const valueExpr = (0, ast_1.parseExpr)((0, codegen_1.genExpr)(exp), context, exp);
|
||
|
if (!valueExpr) {
|
||
|
continue;
|
||
|
}
|
||
|
properties.push(createObjectProperty(arg.content, valueExpr));
|
||
|
}
|
||
|
else {
|
||
|
// :[dynamic]="dynamic"
|
||
|
const leftExpr = (0, ast_1.parseExpr)((0, codegen_1.genExpr)(arg), context, exp);
|
||
|
if (!leftExpr) {
|
||
|
continue;
|
||
|
}
|
||
|
const valueExpr = (0, ast_1.parseExpr)((0, codegen_1.genExpr)(exp), context, exp);
|
||
|
if (!valueExpr) {
|
||
|
continue;
|
||
|
}
|
||
|
properties.push((0, types_1.objectProperty)((0, types_1.logicalExpression)('||', leftExpr, (0, types_1.stringLiteral)('')), valueExpr, true));
|
||
|
}
|
||
|
}
|
||
|
// 即保留 id 属性,又补充到 props 中
|
||
|
if (!isIdProp) {
|
||
|
props.splice(i, 1);
|
||
|
i--;
|
||
|
}
|
||
|
}
|
||
|
if (properties.length) {
|
||
|
props.push((0, uni_cli_shared_1.createBindDirectiveNode)(utils_1.ATTR_VUE_PROPS, (0, codegen_1.genBabelExpr)((0, types_1.objectExpression)(properties))));
|
||
|
}
|
||
|
}
|
||
|
exports.rewriteBinding = rewriteBinding;
|
||
|
function createVBindSpreadElement(prop, context) {
|
||
|
const { arg, exp } = prop;
|
||
|
if (!exp) {
|
||
|
return;
|
||
|
}
|
||
|
if (!arg) {
|
||
|
const argument = (0, ast_1.parseExpr)((0, codegen_1.genExpr)(exp), context, exp);
|
||
|
if (!argument) {
|
||
|
return;
|
||
|
}
|
||
|
return (0, types_1.spreadElement)(argument);
|
||
|
}
|
||
|
}
|
||
|
function isPropsBinding({ arg }) {
|
||
|
return (arg &&
|
||
|
arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
|
||
|
arg.content === utils_1.ATTR_VUE_PROPS);
|
||
|
}
|
||
|
exports.isPropsBinding = isPropsBinding;
|
||
|
function rewritePropsBinding(dir, node, context) {
|
||
|
dir.exp = (0, compiler_core_1.createSimpleExpression)((0, codegen_1.genBabelExpr)((0, utils_1.rewirteWithHelper)(runtimeHelpers_1.RENDER_PROPS, (0, ast_1.parseExpr)(dir.exp, context), dir.loc, context)) + ((0, vIf_1.isIfElementNode)(node) && node.vIf.name === 'else' ? `||''` : ''));
|
||
|
}
|
||
|
exports.rewritePropsBinding = rewritePropsBinding;
|