"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.rewriteSlot = void 0; const compiler_core_1 = require("@vue/compiler-core"); const shared_1 = require("@vue/shared"); const uni_shared_1 = require("@dcloudio/uni-shared"); const runtimeHelpers_1 = require("../runtimeHelpers"); const codegen_1 = require("../codegen"); const transform_1 = require("../transform"); const transformElement_1 = require("./transformElement"); const utils_1 = require("./utils"); const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); const __1 = require(".."); const ast_1 = require("../ast"); function rewriteSlot(node, context) { let slotName = `"${uni_shared_1.SLOT_DEFAULT_NAME}"`; let hasOtherDir = false; const nonNameProps = []; const { props } = node; // 默认插槽强制设置name if (!(0, compiler_core_1.findProp)(node, 'name')) { props.unshift((0, uni_cli_shared_1.createAttributeNode)('name', 'default')); } for (let i = 0; i < props.length; i++) { const p = props[i]; if (p.type === 6 /* NodeTypes.ATTRIBUTE */) { if (p.value) { if (p.name === 'name') { p.value.content = (0, uni_shared_1.dynamicSlotName)(p.value.content); slotName = JSON.stringify(p.value.content); } else { p.name = (0, shared_1.camelize)(p.name); nonNameProps.push(p); } } } else { if (p.name !== 'bind') { hasOtherDir = true; } if (p.name === 'bind' && (0, compiler_core_1.isStaticArgOf)(p.arg, 'name')) { if (p.exp) { slotName = (0, compiler_core_1.createCompoundExpression)([ context.helperString(__1.DYNAMIC_SLOT) + '(', p.exp, ')', ]); let slotKey; const keys = parseVForKeyAlias(context); if (keys.length) { const babelNode = (0, ast_1.parseExpr)(p.exp, context); // 在 v-for 中,判断是否插槽名使用 v-for 的 key 变量 if (babelNode && (0, utils_1.isReferencedByIds)(babelNode, keys)) { slotKey = parseScopedSlotKey(context); } } p.exp = (0, utils_1.rewriteExpression)((0, compiler_core_1.createCompoundExpression)([ context.helperString(__1.DYNAMIC_SLOT) + '(', p.exp, slotKey ? `+'-'+` + slotKey : '', ')', ]), context); } } else { if (p.name === 'bind' && p.arg && (0, compiler_core_1.isStaticExp)(p.arg)) { p.arg.content = (0, shared_1.camelize)(p.arg.content); } nonNameProps.push(p); } } } if (hasOtherDir) { context.onError((0, compiler_core_1.createCompilerError)(36 /* ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, node.loc)); } if (nonNameProps.length > 0) { (0, transformElement_1.processProps)(node, context, nonNameProps); const properties = []; nonNameProps.forEach((prop) => { const property = transformProperty(prop, context); property && properties.push(property); }); if (properties.length) { transformScopedSlotName(node, context); const vForIndexAlias = parseVForIndexAlias(context); (0, utils_1.rewriteExpression)((0, compiler_core_1.createCompoundExpression)([ context.helperString(runtimeHelpers_1.RENDER_SLOT) + '(', slotName, ',', `{${properties.join(',')}}`, `${vForIndexAlias ? ',' + parseScopedSlotKey(context) : ''}`, ')', ]), context); } else { // 非作用域默认插槽直接移除命名 if (slotName === `"${uni_shared_1.SLOT_DEFAULT_NAME}"`) { (0, utils_1.removeAttribute)(node, 'name'); } } } else { // 非作用域默认插槽直接移除命名 if (slotName === `"${uni_shared_1.SLOT_DEFAULT_NAME}"`) { (0, utils_1.removeAttribute)(node, 'name'); } } } exports.rewriteSlot = rewriteSlot; function parseVForIndexAlias(context) { let { currentScope } = context; while (currentScope) { if ((0, transform_1.isVForScope)(currentScope) && !(0, transform_1.isScopedSlotVFor)(currentScope)) { return currentScope.indexAlias; } currentScope = currentScope.parent; } } function transformScopedSlotName(node, context) { if (!context.miniProgram.slot.dynamicSlotNames) { return; } const slotKey = parseScopedSlotKey(context); if (!slotKey) { return; } const nameProps = (0, compiler_core_1.findProp)(node, 'name'); if (nameProps && nameProps.type === 6 /* NodeTypes.ATTRIBUTE */ && nameProps.value) { const { props } = node; props.splice(props.indexOf(nameProps), 1, createScopedSlotDirectiveNode(nameProps.value.content, slotKey, context)); } } function createScopedSlotDirectiveNode(name, slotKey, context) { const dir = (0, uni_cli_shared_1.createBindDirectiveNode)('name', (0, utils_1.rewriteExpression)((0, compiler_core_1.createSimpleExpression)(`"${name}-"+` + slotKey), context) .content); // 存储原始的 slot 名称 dir.slotName = name; return dir; } function parseVForKeyAlias(context) { let { currentScope } = context; const keys = []; while (currentScope) { if ((0, transform_1.isVForScope)(currentScope) && !(0, transform_1.isScopedSlotVFor)(currentScope)) { keys.push(currentScope.keyAlias); } currentScope = currentScope.parent; } return keys; } function parseVForIndexes(context) { let { currentScope } = context; const indexes = []; while (currentScope) { if ((0, transform_1.isVForScope)(currentScope) && !(0, transform_1.isScopedSlotVFor)(currentScope)) { indexes.push(currentScope.indexAlias); } currentScope = currentScope.parent; } return indexes; } function parseSlotKeyByVForIndexes(indexes) { return indexes.reverse().join(`+'-'+`); } function parseScopedSlotKey(context) { const indexes = parseVForIndexes(context); const inFor = !!indexes.length; if (inFor) { return parseSlotKeyByVForIndexes(indexes); } } function transformProperty(dir, _) { if ((0, uni_cli_shared_1.isDirectiveNode)(dir)) { if (!dir.arg || !dir.exp) { return; } const isStaticArg = dir.arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && dir.arg.isStatic; if (isStaticArg) { return `${dir.arg.content}:${(0, codegen_1.genExpr)(dir.exp)}`; } return `[${(0, codegen_1.genExpr)(dir.arg)}||'']:${(0, codegen_1.genExpr)(dir.exp)}`; } if (dir.value) { return `${dir.name}:${(0, codegen_1.genExpr)(dir.value)}`; } }