import * as React from 'react' // import { WrapperChild, WrapperResult, ComponentManifest, FieldTypes } from '../types' import { ComponentManifest, Props, FieldTypes, EditTypes, UITable } from '../types' // const renderChildren = (engine: any, children: any): any => { // // TODO: 可能会有xss攻击风险,但是暂时先不处理 // if (Array.isArray(children)) { // return children.map(item => renderChildren(engine, item)) // } // if (typeof children === 'object') { // if (typeof children.$$typeof === 'symbol') { // // react组件,直接返回 // return children // } else if (children.type) { // // 有type说明是ui meta,走engine渲染 // if (!engine) { // console.warn('Cannot parse ui meta because no engine provides!') // return null // } // return engine(children) // } // } else if (typeof children === 'string') { // // 如果是字符串,需要根据情况做不同的处理 // try { // // 如果可以被 JSON.parse 解析,则以object方式继续渲染 // return renderChildren(engine, JSON.parse(children)) // } catch (error) { // // 如果JSON.parse失败,则有可能是 html 或者 普通文本,两种方式都可以留到后面用dangerouslySetInnerHTML处理 // } // } // return
// } // function parseProps (origProps: any, engine: any, manifest?: ComponentManifest): any { // const props = { ...origProps } // // 处理props,包括处理 children,以及将一些props做类型转换 // if (props.children) { // props.children = renderChildren(engine, props.children) // } // // 根据manifest处理其它字段转换 // if (manifest) { // const propsKeySet = new Set(Object.keys(props)) // for (const propsItem of manifest.props || []) { // const { name, type } = propsItem // if (!propsKeySet.has(propsItem.name)) { // continue // } // if (type === FieldTypes.action) { // // Action(实际是String) => 函数 // const actionName = `${props[name]}` // props[name] = (...args: any[]) => { // return props.__dispatch__ // ? props.__dispatch__(props[name], ...args) // : console.log(`Action: ${actionName}`) // } // } else if (type === FieldTypes.date) { // // String => Date // props[name] = new Date(props[name]) // } else if (type === FieldTypes.array || type === FieldTypes.object) { // // String => JSON.parse 处理后的object // try { // if (props[name]) { // props[name] = JSON.parse(props[name]) // } // } catch (error) { // console.warn(error) // props[name] = null // } // } else if (type === FieldTypes.child) { // props[name] = renderChildren(engine, props[name]) // } // } // } // return props // } export interface WrapOptions { excludeNidAndUiType?: boolean } // function wrapper (orig: WrapperChild, options: WrapOptions = {}): WrapperResult { // return (props: any, engine?: any) => { // const { nid, uitype } = props || {} // const divProps = { nid, uitype } // const { excludeNidAndUiType, manifest } = options // const renderEngine = engine && engine.render ? engine.render : engine // const newProps = parseProps(props, renderEngine, manifest) // const innerComp = orig(newProps, renderEngine) // if (excludeNidAndUiType) { // return innerComp // } // return
{innerComp}
// } // } const wrapManifest = (manifest: ComponentManifest, options: WrapOptions = {}): ComponentManifest => { if (!manifest) { return manifest } const styleProp: Props = { name: 'style', type: FieldTypes.action, showDesign: true, designConfig: { label: '公共样式', type: EditTypes.IframeModal, help: '', props: { caption: '公共样式', iframeUrl: '/CssSelect', iframeId: 'mobileCssIframeModal', iframeContext: 'mobileCssIframeModal', addText: '新增样式', editText: '修改样式', message: true, isRequired: false, footer: true } } } const classNameProp: Props = { name: 'className', type: FieldTypes.string, defaultValue: '', showDesign: true, designConfig: { type: EditTypes.Text, label: 'className', isRequired: false, help: '自定义类名', props: {} } } // add default props in manifest manifest.props = manifest.props || [] const props = manifest.props const propsNameSet = new Set(props.map(item => item.name)) // style if (!propsNameSet.has('style')) { props.push(styleProp) } // className if (!propsNameSet.has('className')) { props.push(classNameProp) } // 填充默认的 uiTable if (!manifest.uiTable) { manifest.uiTable = UITable.BillItemBase } return manifest } /** * * @param Comp 要封装的组件 * @param manifest 组件描述 * @param options 选项 */ const wrapper = (Comp: any, manifest: ComponentManifest, options: WrapOptions = {}): any => class Wrapped extends React.Component { static manifest = wrapManifest(manifest, options) renderWithoutWrapper = (): React.ReactNode => { return } render = (): React.ReactNode => { const { nid, uitype } = this.props || {} const divProps = { nid, uitype } return options.excludeNidAndUiType ? this.renderWithoutWrapper() :
{this.renderWithoutWrapper()}
} } export default wrapper