You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
7.6 KiB
210 lines
7.6 KiB
"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` : ``}`, |
|
`)`, |
|
]); |
|
}
|
|
|