const t = require('@babel/types') const { METHOD_CREATE_ELEMENT, ATTR_DATA_EVENT_OPTS, ATTR_DATA_COM_TYPE, ATTR_DATA_EVENT_LIST, ATTR_DATA_EVENT_PARAMS, ATTE_DATA_CUSTOM_HIDDEN, INTERNAL_EVENT_WRAP } = require('../../../constants') const processRef = require('./ref') const processAttrs = require('./attrs') const processClass = require('./class') const processEvent = require('./event') const processStyle = require('./style') const processModel = require('./model') const processDir = require('./directives') module.exports = function traverseData (path, state, tagName) { if (path.node.$mpProcessed) { return } path.node.$mpProcessed = true const paths = {} const propertyPaths = path.get('properties') propertyPaths.forEach((propertyPath, index) => { paths[propertyPath.node.key.name] = propertyPath }) const addAttrProperties = [] const isComponent = state.options.platform.isComponent(tagName) const processes = [processAttrs, processRef, processClass, processModel, processDir, processEvent, processStyle] // ref(add staticClass) > class,model,dir(add input event)>event processes.forEach(process => { process(paths, path, state, isComponent, tagName).forEach((property) => { addAttrProperties.push(property) }) }) // 该组件是引入的小程序组件 const wxComponent = state.options.wxComponents[tagName] if (wxComponent) { addAttrProperties.push( t.objectProperty( t.stringLiteral(ATTR_DATA_COM_TYPE), t.stringLiteral('wx') ) ) if (state.options.platform.name === 'mp-alipay') { addAttrProperties.push( t.objectProperty( t.stringLiteral('ref'), t.stringLiteral('__r') ) ) const properties = path.node.properties.find(prop => prop.key.name === 'on').value.properties const list = [] for (let index = 0; index < properties.length; index++) { const element = properties[index] if (element.value.value === '__e') { list.push(element.key.value) } } addAttrProperties.push( t.objectProperty( t.stringLiteral(ATTR_DATA_EVENT_LIST), t.stringLiteral(list.join(',')) ) ) if (wxComponent.startsWith('plugin://')) { const wrapperTag = 'plugin-wrapper' const orgPath = path.parentPath const orgNode = orgPath.node const args = orgNode.arguments const orgTag = args[0] orgTag.$mpPlugin = true args[0] = t.stringLiteral(wrapperTag) const orgOptions = args[1] const orgOptionsProps = orgOptions.properties const targetAttrs = [] const targetOptionsProps = [ t.objectProperty(t.identifier('attrs'), t.objectExpression(targetAttrs)) ] const uniAttrs = [ ATTR_DATA_EVENT_OPTS, ATTR_DATA_COM_TYPE, ATTR_DATA_EVENT_PARAMS, ATTR_DATA_EVENT_LIST, ATTE_DATA_CUSTOM_HIDDEN, 'vue-id' ] for (let a = orgOptionsProps.length - 1; a >= 0; a--) { const prop = orgOptionsProps[a] if (prop.key.name === 'attrs') { const attrs = prop.value.properties for (let b = attrs.length - 1; b >= 0; b--) { const element = attrs[b] const key = element.key.value if (!uniAttrs.includes(key)) { attrs.splice(b, 1) targetAttrs.push(element) } } attrs.push(t.objectProperty(t.stringLiteral('onPluginWrap'), t.stringLiteral(INTERNAL_EVENT_WRAP))) } else if (prop.key.name === 'on') { const ons = prop.value.properties ons.forEach(item => { const attrs = path.node.properties.find(prop => prop.key.name === 'attrs').value.properties const vueId = attrs.find(prop => prop.key.value === 'vue-id').value const eventName = item.key.value targetAttrs.push(t.objectProperty(t.stringLiteral(eventName), t.binaryExpression('+', t.stringLiteral(eventName), vueId))) }) } else { orgOptionsProps.splice(a, 1) targetOptionsProps.push(prop) } } const orgChild = args[2] const targetOptions = t.objectExpression(targetOptionsProps) targetOptions.$mpProcessed = true const targetArguments = [ orgTag, targetOptions ] if (orgChild) { targetArguments.push(orgChild) } const targetNode = t.callExpression(t.identifier(METHOD_CREATE_ELEMENT), targetArguments) args[2] = targetNode } } } if (addAttrProperties.length) { const attrsPath = paths.attrs if (attrsPath) { attrsPath.node.value.properties = attrsPath.node.value.properties.concat(addAttrProperties) } else { path.node.properties.unshift( t.objectProperty(t.identifier('attrs'), t.objectExpression(addAttrProperties)) ) } } }