"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transformModel = void 0; const shared_1 = require("@vue/shared"); const compiler_core_1 = require("@vue/compiler-core"); const compiler_dom_1 = require("@vue/compiler-dom"); const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); const runtimeHelpers_1 = require("../runtimeHelpers"); const codegen_1 = require("../codegen"); const vOn_1 = require("./vOn"); const transformModel = (dir, node, _context) => { const context = _context; const baseResult = (0, compiler_core_1.transformModel)(dir, node, _context); // base transform has errors OR component v-model (only need props) if (!baseResult.props.length || node.tagType === 1 /* ElementTypes.COMPONENT */) { return transformComponentVModel(baseResult.props, node, context); } if (dir.arg) { context.onError((0, compiler_dom_1.createDOMCompilerError)(56 /* DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc)); } function checkDuplicatedValue() { const value = (0, compiler_core_1.findProp)(node, 'value'); if (value) { context.onError((0, compiler_dom_1.createDOMCompilerError)(58 /* DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE */, value.loc)); } } const { tag } = node; if (tag === 'input' || tag === 'textarea') { checkDuplicatedValue(); } else { context.onError((0, compiler_dom_1.createDOMCompilerError)(55 /* DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc)); } if (dir.modifiers.length) { const arg = dir.arg; const modifiers = dir.modifiers .map((m) => ((0, compiler_core_1.isSimpleIdentifier)(m) ? m : JSON.stringify(m)) + `: true`) .join(`, `); const modifiersKey = arg ? (0, compiler_core_1.isStaticExp)(arg) ? `${arg.content}Modifiers` : (0, compiler_core_1.createCompoundExpression)([arg, ' + "Modifiers"']) : `modelModifiers`; baseResult.props.push((0, compiler_core_1.createObjectProperty)(modifiersKey, (0, compiler_core_1.createSimpleExpression)(`{ ${modifiers} }`, false, dir.loc, 2 /* ConstantTypes.CAN_HOIST */))); } return transformElementVModel(baseResult.props, node, context); }; exports.transformModel = transformModel; function findInputDirectiveNode(props) { return props.find((prop) => prop.type === 7 /* NodeTypes.DIRECTIVE */ && prop.name === 'on' && prop.arg?.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && prop.arg.content === 'input'); } function transformElementVModel(props, node, context) { const dirs = transformVModel(props, node, context, { isComponent: false, binding: 'value', event: 'input', formatEventCode(code) { return code.replace(/=\s\$event/g, `= $event.detail.value`); }, }); if (dirs.length === 2) { // 快手小程序的 input v-model 被转换到 data-e-o 中,补充到 data-e-o 中 const inputExp = findDatasetEventOpts(node); if (inputExp) { inputExp.children[2] = combineVOn(dirs[1].exp, inputExp.children[2], node, context); dirs.length = 1; } else { const inputDir = findInputDirectiveNode(node.props); if (inputDir && inputDir.exp) { // 合并到已有的 input 事件中 inputDir.exp = combineVOn(dirs[1].exp, inputDir.exp, node, context); dirs.length = 1; } } } return { props: dirs }; } /** * { * "type": 7, * "name": "bind", * "loc": {}, * "modifiers": [], * "arg": { * "type": 4, * "loc": {}, * "content": "data-e-o", * "isStatic": true, * "constType": 3 * }, * "exp": { * "type": 8, * "loc": {}, * "children": ["{", { * "type": 8, * "loc": {}, * "children": ["'input'", ": ", { * "type": 8, * "loc": {}, * "children": ["_o(", { * "type": 4, * "content": "_ctx.input", * "isStatic": false, * "constType": 0, * "loc": {} * }, ")"] * }, ","] * }, "}"] * } * } * @param node * @returns */ function findDatasetEventOpts(node) { const eventOptsProp = (0, compiler_core_1.findProp)(node, uni_cli_shared_1.ATTR_DATASET_EVENT_OPTS, true, false); if (!eventOptsProp) { return; } const { exp } = eventOptsProp; if (exp?.type !== 8 /* NodeTypes.COMPOUND_EXPRESSION */) { return; } for (let i = 0; i < exp.children.length; i++) { const childExp = exp.children[i]; if ((0, shared_1.isSymbol)(childExp) || (0, shared_1.isString)(childExp)) { continue; } if (childExp.type !== 8 /* NodeTypes.COMPOUND_EXPRESSION */) { continue; } if (childExp.children[0] !== `'input'`) { continue; } const inputExp = childExp.children[2]; if ((0, shared_1.isSymbol)(inputExp) || (0, shared_1.isString)(inputExp) || inputExp.type !== 8 /* NodeTypes.COMPOUND_EXPRESSION */) { continue; } return childExp; } } function parseVOn(exp, context) { return (0, codegen_1.genExpr)(exp).slice(context.helperString(runtimeHelpers_1.V_ON).length + 1, -1); } function combineVOn(exp1, exp2, node, context) { return (0, vOn_1.wrapperVOn)((0, compiler_core_1.createCompoundExpression)([ `[`, parseVOn(exp1, context), ',', parseVOn(exp2, context), `]`, ]), node, context); } function transformComponentVModel(props, node, context) { return { props: transformVModel(props, node, context, { isComponent: true, formatEventCode(code) { return code; }, }), }; } function transformVModel(props, node, context, { isComponent, binding, event, formatEventCode, }) { if (props.length < 2) { return []; } const { key: modelValueArg, value: modelValeExpr } = props[0]; const { key: onUpdateArg, value: onUpdateExpr } = props[1]; if (modelValueArg.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */) { return []; } if (onUpdateArg.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */ || !onUpdateArg.content.startsWith('onUpdate:')) { return []; } const vBindModelValue = (0, uni_cli_shared_1.createBindDirectiveNode)(binding || modelValueArg.content, (0, codegen_1.genExpr)(modelValeExpr)); const modifiers = parseVModelModifiers(props[2]); // onUpdateExpr 通常是 ExpressionNode 或者被 cache 的 ExpressionNode const vOnValue = (onUpdateExpr.type === 20 /* NodeTypes.JS_CACHE_EXPRESSION */ ? onUpdateExpr.value : onUpdateExpr); const vOnUpdate = (0, uni_cli_shared_1.createOnDirectiveNode)(event || (0, shared_1.camelize)(onUpdateArg.content.replace('onUpdate:', 'update-')), formatEventCode((0, codegen_1.genExpr)((0, vOn_1.wrapperVOn)(modifiers ? wrapperVModelModifiers(vOnValue, modifiers, context, isComponent) : vOnValue, node, context)))); return [vBindModelValue, vOnUpdate]; } function parseVModelModifiers(property) { if (property && (0, uni_cli_shared_1.isSimpleExpressionNode)(property.key) && property.key.content.endsWith('Modifiers') && (0, uni_cli_shared_1.isSimpleExpressionNode)(property.value)) { return property.value.content; } } function wrapperVModelModifiers(exp, modifiers, context, isComponent = false) { return (0, compiler_core_1.createCompoundExpression)([ `${context.helperString(runtimeHelpers_1.WITH_MODEL_MODIFIERS)}(`, exp, ',', modifiers, `${isComponent ? `, true` : ``}`, `)`, ]); }