UNPKG

@alilc/lowcode-renderer-core

Version:
526 lines (517 loc) 25.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.leafWrapper = leafWrapper; var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); var _lowcodeTypes = require("@alilc/lowcode-types"); var _lowcodeUtils = require("@alilc/lowcode-utils"); var _common = require("../utils/common"); var _adapter = _interopRequireDefault(require("../adapter")); var _logger = _interopRequireDefault(require("../utils/logger")); var _excluded = ["visible"], _excluded2 = ["forwardedRef"]; var RerenderType = /*#__PURE__*/function (RerenderType) { RerenderType["All"] = "All"; RerenderType["ChildChanged"] = "ChildChanged"; RerenderType["PropsChanged"] = "PropsChanged"; RerenderType["VisibleChanged"] = "VisibleChanged"; RerenderType["MinimalRenderUnit"] = "MinimalRenderUnit"; return RerenderType; }(RerenderType || {}); // 缓存 Leaf 层组件,防止重新渲染问题 var LeafCache = function LeafCache(documentId, device) { this.documentId = documentId; this.device = device; /** 组件缓存 */ this.component = new Map(); /** * 状态缓存,场景:属性变化后,改组件被销毁,state 为空,没有展示修改后的属性 */ this.state = new Map(); /** * 订阅事件缓存,导致 rerender 的订阅事件 */ this.event = new Map(); this.ref = new Map(); }; var cache; /** 部分没有渲染的 node 节点进行兜底处理 or 渲染方式没有渲染 LeafWrapper */ function initRerenderEvent(_ref) { var _cache$event$get, _cache$event$get2, _leaf$onPropChange, _leaf$onChildrenChang, _leaf$onVisibleChange; var schema = _ref.schema, __debug = _ref.__debug, container = _ref.container, getNode = _ref.getNode; var leaf = getNode === null || getNode === void 0 ? void 0 : getNode(schema.id); if (!leaf || (_cache$event$get = cache.event.get(schema.id)) !== null && _cache$event$get !== void 0 && _cache$event$get.clear || leaf === cache.event.get(schema.id)) { return; } (_cache$event$get2 = cache.event.get(schema.id)) === null || _cache$event$get2 === void 0 ? void 0 : _cache$event$get2.dispose.forEach(function (disposeFn) { return disposeFn && disposeFn(); }); var debounceRerender = (0, _common.debounce)(function () { container.rerender(); }, 20); cache.event.set(schema.id, { clear: false, leaf: leaf, dispose: [leaf === null || leaf === void 0 ? void 0 : (_leaf$onPropChange = leaf.onPropChange) === null || _leaf$onPropChange === void 0 ? void 0 : _leaf$onPropChange.call(leaf, function () { if (!container.autoRepaintNode) { return; } __debug(schema.componentName + "[" + schema.id + "] leaf not render in SimulatorRendererView, leaf onPropsChange make rerender"); debounceRerender(); }), leaf === null || leaf === void 0 ? void 0 : (_leaf$onChildrenChang = leaf.onChildrenChange) === null || _leaf$onChildrenChang === void 0 ? void 0 : _leaf$onChildrenChang.call(leaf, function () { if (!container.autoRepaintNode) { return; } __debug(schema.componentName + "[" + schema.id + "] leaf not render in SimulatorRendererView, leaf onChildrenChange make rerender"); debounceRerender(); }), leaf === null || leaf === void 0 ? void 0 : (_leaf$onVisibleChange = leaf.onVisibleChange) === null || _leaf$onVisibleChange === void 0 ? void 0 : _leaf$onVisibleChange.call(leaf, function () { if (!container.autoRepaintNode) { return; } __debug(schema.componentName + "[" + schema.id + "] leaf not render in SimulatorRendererView, leaf onVisibleChange make rerender"); debounceRerender(); })] }); } /** 渲染的 node 节点全局注册事件清除 */ function clearRerenderEvent(id) { var _cache$event$get3, _cache$event$get4, _cache$event$get4$dis; if ((_cache$event$get3 = cache.event.get(id)) !== null && _cache$event$get3 !== void 0 && _cache$event$get3.clear) { return; } (_cache$event$get4 = cache.event.get(id)) === null || _cache$event$get4 === void 0 ? void 0 : (_cache$event$get4$dis = _cache$event$get4.dispose) === null || _cache$event$get4$dis === void 0 ? void 0 : _cache$event$get4$dis.forEach(function (disposeFn) { return disposeFn && disposeFn(); }); cache.event.set(id, { clear: true, dispose: [] }); } // 给每个组件包裹一个 HOC Leaf,支持组件内部属性变化,自响应渲染 function leafWrapper(Comp, _ref2) { var _baseRenderer$props, _baseRenderer$props$d, _baseRenderer$props2, _baseRenderer$props$d2, _baseRenderer$props3, _baseRenderer$props4, _baseRenderer$props5, _baseRenderer$props6, _host$designer; var schema = _ref2.schema, baseRenderer = _ref2.baseRenderer, componentInfo = _ref2.componentInfo, scope = _ref2.scope; var __debug = baseRenderer.__debug, getProps = baseRenderer.__getComponentProps, getChildren = baseRenderer.__getSchemaChildrenVirtualDom, __parseData = baseRenderer.__parseData; var engine = baseRenderer.context.engine; var host = (_baseRenderer$props = baseRenderer.props) === null || _baseRenderer$props === void 0 ? void 0 : _baseRenderer$props.__host; var curDocumentId = (_baseRenderer$props$d = (_baseRenderer$props2 = baseRenderer.props) === null || _baseRenderer$props2 === void 0 ? void 0 : _baseRenderer$props2.documentId) !== null && _baseRenderer$props$d !== void 0 ? _baseRenderer$props$d : ''; var curDevice = (_baseRenderer$props$d2 = (_baseRenderer$props3 = baseRenderer.props) === null || _baseRenderer$props3 === void 0 ? void 0 : _baseRenderer$props3.device) !== null && _baseRenderer$props$d2 !== void 0 ? _baseRenderer$props$d2 : ''; var getNode = (_baseRenderer$props4 = baseRenderer.props) === null || _baseRenderer$props4 === void 0 ? void 0 : _baseRenderer$props4.getNode; var container = (_baseRenderer$props5 = baseRenderer.props) === null || _baseRenderer$props5 === void 0 ? void 0 : _baseRenderer$props5.__container; var setSchemaChangedSymbol = (_baseRenderer$props6 = baseRenderer.props) === null || _baseRenderer$props6 === void 0 ? void 0 : _baseRenderer$props6.setSchemaChangedSymbol; var editor = host === null || host === void 0 ? void 0 : (_host$designer = host.designer) === null || _host$designer === void 0 ? void 0 : _host$designer.editor; var runtime = _adapter["default"].getRuntime(); var forwardRef = runtime.forwardRef, createElement = runtime.createElement; var Component = runtime.Component; var componentCacheId = schema.id; if (!cache || curDocumentId && curDocumentId !== cache.documentId || curDevice && curDevice !== cache.device) { var _cache; (_cache = cache) === null || _cache === void 0 ? void 0 : _cache.event.forEach(function (event) { var _event$dispose; (_event$dispose = event.dispose) === null || _event$dispose === void 0 ? void 0 : _event$dispose.forEach(function (disposeFn) { return disposeFn && disposeFn(); }); }); cache = new LeafCache(curDocumentId, curDevice); } if (!(0, _lowcodeUtils.isReactComponent)(Comp)) { _logger["default"].error(schema.componentName + " component may be has errors: ", Comp); } initRerenderEvent({ schema: schema, __debug: __debug, container: container, getNode: getNode }); if (curDocumentId && cache.component.has(componentCacheId) && cache.component.get(componentCacheId).Comp === Comp) { return cache.component.get(componentCacheId).LeafWrapper; } var LeafHoc = /*#__PURE__*/function (_Component) { function LeafHoc(props, context) { var _this; _this = _Component.call(this, props, context) || this; // 监听以下事件,当变化时更新自己 _this.recordInfo = {}; _this.curEventLeaf = void 0; _this.disposeFunctions = []; _this.__component_tag = 'leafWrapper'; _this.renderUnitInfo = void 0; // 最小渲染单元做防抖处理 _this.makeUnitRenderDebounced = (0, _common.debounce)(function () { var _this$leaf, _this$leaf$export, _this$leaf2; _this.beforeRender(RerenderType.MinimalRenderUnit); var schema = (_this$leaf = _this.leaf) === null || _this$leaf === void 0 ? void 0 : (_this$leaf$export = _this$leaf["export"]) === null || _this$leaf$export === void 0 ? void 0 : _this$leaf$export.call(_this$leaf, _lowcodeTypes.IPublicEnumTransformStage.Render); if (!schema) { return; } var nextProps = getProps(schema, scope, Comp, componentInfo); var children = getChildren(schema, scope, Comp); var nextState = { nodeProps: nextProps, nodeChildren: children, childrenInState: true }; if ('children' in nextProps) { nextState.nodeChildren = nextProps.children; } __debug(((_this$leaf2 = _this.leaf) === null || _this$leaf2 === void 0 ? void 0 : _this$leaf2.componentName) + "(" + _this.props.componentId + ") MinimalRenderUnit Render!"); _this.setState(nextState); }, 20); _this.recordTime = function () { var _host$designer2, _host$designer2$curre, _host$designer2$curre2, _this$recordInfo$node, _this$leaf3; if (!_this.recordInfo.startTime) { return; } var endTime = Date.now(); var nodeCount = host === null || host === void 0 ? void 0 : (_host$designer2 = host.designer) === null || _host$designer2 === void 0 ? void 0 : (_host$designer2$curre = _host$designer2.currentDocument) === null || _host$designer2$curre === void 0 ? void 0 : (_host$designer2$curre2 = _host$designer2$curre.getNodeCount) === null || _host$designer2$curre2 === void 0 ? void 0 : _host$designer2$curre2.call(_host$designer2$curre); var componentName = ((_this$recordInfo$node = _this.recordInfo.node) === null || _this$recordInfo$node === void 0 ? void 0 : _this$recordInfo$node.componentName) || ((_this$leaf3 = _this.leaf) === null || _this$leaf3 === void 0 ? void 0 : _this$leaf3.componentName) || 'UnknownComponent'; editor === null || editor === void 0 ? void 0 : editor.eventBus.emit(_lowcodeTypes.GlobalEvent.Node.Rerender, { componentName: componentName, time: endTime - _this.recordInfo.startTime, type: _this.recordInfo.type, nodeCount: nodeCount }); _this.recordInfo.startTime = null; }; _this.makeUnitRender = function () { _this.makeUnitRenderDebounced(); }; __debug(schema.componentName + "[" + _this.props.componentId + "] leaf render in SimulatorRendererView"); clearRerenderEvent(componentCacheId); _this.curEventLeaf = _this.leaf; cache.ref.set(componentCacheId, { makeUnitRender: _this.makeUnitRender }); var cacheState = cache.state.get(componentCacheId); if (!cacheState || cacheState.__tag !== props.__tag) { cacheState = _this.getDefaultState(props); } _this.state = cacheState; return _this; } (0, _inheritsLoose2["default"])(LeafHoc, _Component); var _proto = LeafHoc.prototype; _proto.componentDidUpdate = function componentDidUpdate() { this.recordTime(); }; _proto.componentDidMount = function componentDidMount() { var _leaf = this.leaf; this.initOnPropsChangeEvent(_leaf); this.initOnChildrenChangeEvent(_leaf); this.initOnVisibleChangeEvent(_leaf); this.recordTime(); }; _proto.getDefaultState = function getDefaultState(nextProps) { var _this$leaf4, _this$leaf4$export; var _ref3 = nextProps.__inner__ || ((_this$leaf4 = this.leaf) === null || _this$leaf4 === void 0 ? void 0 : (_this$leaf4$export = _this$leaf4["export"]) === null || _this$leaf4$export === void 0 ? void 0 : _this$leaf4$export.call(_this$leaf4, _lowcodeTypes.IPublicEnumTransformStage.Render)) || {}, _ref3$hidden = _ref3.hidden, hidden = _ref3$hidden === void 0 ? false : _ref3$hidden, _ref3$condition = _ref3.condition, condition = _ref3$condition === void 0 ? true : _ref3$condition; return { nodeChildren: null, childrenInState: false, visible: !hidden, condition: __parseData === null || __parseData === void 0 ? void 0 : __parseData(condition, scope), nodeCacheProps: {}, nodeProps: {} }; }; _proto.setState = function setState(state) { cache.state.set(componentCacheId, (0, _extends2["default"])({}, this.state, state, { __tag: this.props.__tag })); _Component.prototype.setState.call(this, state); } /** 由于内部属性变化,在触发渲染前,会执行该函数 */; _proto.beforeRender = function beforeRender(type, node) { this.recordInfo.startTime = Date.now(); this.recordInfo.type = type; this.recordInfo.node = node; setSchemaChangedSymbol === null || setSchemaChangedSymbol === void 0 ? void 0 : setSchemaChangedSymbol(true); }; _proto.judgeMiniUnitRender = function judgeMiniUnitRender() { var _this$leaf5; if (!this.renderUnitInfo) { this.getRenderUnitInfo(); } var renderUnitInfo = this.renderUnitInfo || { singleRender: true }; if (renderUnitInfo.singleRender) { return; } var ref = cache.ref.get(renderUnitInfo.minimalUnitId); if (!ref) { __debug('Cant find minimalRenderUnit ref! This make rerender!'); container === null || container === void 0 ? void 0 : container.rerender(); return; } __debug(((_this$leaf5 = this.leaf) === null || _this$leaf5 === void 0 ? void 0 : _this$leaf5.componentName) + "(" + this.props.componentId + ") need render, make its minimalRenderUnit " + renderUnitInfo.minimalUnitName + "(" + renderUnitInfo.minimalUnitId + ")"); ref.makeUnitRender(); }; _proto.getRenderUnitInfo = function getRenderUnitInfo(leaf) { if (leaf === void 0) { leaf = this.leaf; } // leaf 在低代码组件中存在 mock 的情况,退出最小渲染单元判断 if (!leaf || typeof leaf.isRoot !== 'function') { return; } if (leaf.isRootNode) { this.renderUnitInfo = (0, _extends2["default"])({ singleRender: true }, this.renderUnitInfo || {}); } if (leaf.componentMeta.isMinimalRenderUnit) { this.renderUnitInfo = { minimalUnitId: leaf.id, minimalUnitName: leaf.componentName, singleRender: false }; } if (leaf.hasLoop()) { var _leaf2, _leaf2$parent, _leaf3, _leaf3$parent; // 含有循环配置的元素,父元素是最小渲染单元 this.renderUnitInfo = { minimalUnitId: (_leaf2 = leaf) === null || _leaf2 === void 0 ? void 0 : (_leaf2$parent = _leaf2.parent) === null || _leaf2$parent === void 0 ? void 0 : _leaf2$parent.id, minimalUnitName: (_leaf3 = leaf) === null || _leaf3 === void 0 ? void 0 : (_leaf3$parent = _leaf3.parent) === null || _leaf3$parent === void 0 ? void 0 : _leaf3$parent.componentName, singleRender: false }; } if (leaf.parent) { this.getRenderUnitInfo(leaf.parent); } }; _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { var componentId = nextProps.componentId; if (nextProps.__tag === this.props.__tag) { return null; } var _leaf = getNode === null || getNode === void 0 ? void 0 : getNode(componentId); if (_leaf && this.curEventLeaf && _leaf !== this.curEventLeaf) { this.disposeFunctions.forEach(function (fn) { return fn(); }); this.disposeFunctions = []; this.initOnChildrenChangeEvent(_leaf); this.initOnPropsChangeEvent(_leaf); this.initOnVisibleChangeEvent(_leaf); this.curEventLeaf = _leaf; } var _this$getDefaultState = this.getDefaultState(nextProps), visible = _this$getDefaultState.visible, resetState = (0, _objectWithoutPropertiesLoose2["default"])(_this$getDefaultState, _excluded); this.setState(resetState); } /** 监听参数变化 */; _proto.initOnPropsChangeEvent = function initOnPropsChangeEvent(leaf) { var _this2 = this, _leaf5, _leaf5$onPropChange; if (leaf === void 0) { leaf = this.leaf; } var handlePropsChange = (0, _common.debounce)(function (propChangeInfo) { var _node$export, _leaf4; var key = propChangeInfo.key, _propChangeInfo$newVa = propChangeInfo.newValue, newValue = _propChangeInfo$newVa === void 0 ? null : _propChangeInfo$newVa; var node = leaf; if (key === '___condition___') { var _this2$leaf; var _ref4 = ((_this2$leaf = _this2.leaf) === null || _this2$leaf === void 0 ? void 0 : _this2$leaf["export"](_lowcodeTypes.IPublicEnumTransformStage.Render)) || {}, _ref4$condition = _ref4.condition, condition = _ref4$condition === void 0 ? true : _ref4$condition; var conditionValue = __parseData === null || __parseData === void 0 ? void 0 : __parseData(condition, scope); __debug("key is ___condition___, change condition value to [" + condition + "]"); // 条件表达式改变 _this2.setState({ condition: conditionValue }); return; } // 如果循坏条件变化,从根节点重新渲染 // 目前多层循坏无法判断需要从哪一层开始渲染,故先粗暴解决 if (key === '___loop___') { __debug('key is ___loop___, render a page!'); container === null || container === void 0 ? void 0 : container.rerender(); // 由于 scope 变化,需要清空缓存,使用新的 scope cache.component["delete"](componentCacheId); return; } _this2.beforeRender(RerenderType.PropsChanged); var state = _this2.state; var nodeCacheProps = state.nodeCacheProps; var nodeProps = getProps(node === null || node === void 0 ? void 0 : (_node$export = node["export"]) === null || _node$export === void 0 ? void 0 : _node$export.call(node, _lowcodeTypes.IPublicEnumTransformStage.Render), scope, Comp, componentInfo); if (key && !(key in nodeProps) && key in _this2.props) { // 当 key 在 this.props 中时,且不存在在计算值中,需要用 newValue 覆盖掉 this.props 的取值 nodeCacheProps[key] = newValue; } __debug(((_leaf4 = leaf) === null || _leaf4 === void 0 ? void 0 : _leaf4.componentName) + "[" + _this2.props.componentId + "] component trigger onPropsChange!", nodeProps, nodeCacheProps, key, newValue); _this2.setState('children' in nodeProps ? { nodeChildren: nodeProps.children, nodeProps: nodeProps, childrenInState: true, nodeCacheProps: nodeCacheProps } : { nodeProps: nodeProps, nodeCacheProps: nodeCacheProps }); _this2.judgeMiniUnitRender(); }); var dispose = (_leaf5 = leaf) === null || _leaf5 === void 0 ? void 0 : (_leaf5$onPropChange = _leaf5.onPropChange) === null || _leaf5$onPropChange === void 0 ? void 0 : _leaf5$onPropChange.call(_leaf5, function (propChangeInfo) { if (!_this2.autoRepaintNode) { return; } handlePropsChange(propChangeInfo); }); dispose && this.disposeFunctions.push(dispose); } /** * 监听显隐变化 */; _proto.initOnVisibleChangeEvent = function initOnVisibleChangeEvent(leaf) { var _leaf6, _leaf6$onVisibleChang, _this3 = this; if (leaf === void 0) { leaf = this.leaf; } var dispose = (_leaf6 = leaf) === null || _leaf6 === void 0 ? void 0 : (_leaf6$onVisibleChang = _leaf6.onVisibleChange) === null || _leaf6$onVisibleChang === void 0 ? void 0 : _leaf6$onVisibleChang.call(_leaf6, function (flag) { var _leaf7; if (!_this3.autoRepaintNode) { return; } if (_this3.state.visible === flag) { return; } __debug(((_leaf7 = leaf) === null || _leaf7 === void 0 ? void 0 : _leaf7.componentName) + "[" + _this3.props.componentId + "] component trigger onVisibleChange(" + flag + ") event"); _this3.beforeRender(RerenderType.VisibleChanged); _this3.setState({ visible: flag }); _this3.judgeMiniUnitRender(); }); dispose && this.disposeFunctions.push(dispose); } /** * 监听子元素变化(拖拽,删除...) */; _proto.initOnChildrenChangeEvent = function initOnChildrenChangeEvent(leaf) { var _leaf8, _leaf8$onChildrenChan, _this4 = this; if (leaf === void 0) { leaf = this.leaf; } var dispose = (_leaf8 = leaf) === null || _leaf8 === void 0 ? void 0 : (_leaf8$onChildrenChan = _leaf8.onChildrenChange) === null || _leaf8$onChildrenChan === void 0 ? void 0 : _leaf8$onChildrenChan.call(_leaf8, function (param) { var _leaf9, _leaf9$export; if (!_this4.autoRepaintNode) { return; } var _ref5 = param || {}, type = _ref5.type, node = _ref5.node; _this4.beforeRender(RerenderType.ChildChanged + "-" + type, node); // TODO: 缓存同级其他元素的 children。 // 缓存二级 children Next 查询筛选组件有问题 // 缓存一级 children Next Tab 组件有问题 var nextChild = getChildren((_leaf9 = leaf) === null || _leaf9 === void 0 ? void 0 : (_leaf9$export = _leaf9["export"]) === null || _leaf9$export === void 0 ? void 0 : _leaf9$export.call(_leaf9, _lowcodeTypes.IPublicEnumTransformStage.Render), scope, Comp); __debug(schema.componentName + "[" + _this4.props.componentId + "] component trigger onChildrenChange event", nextChild); _this4.setState({ nodeChildren: nextChild, childrenInState: true }); _this4.judgeMiniUnitRender(); }); dispose && this.disposeFunctions.push(dispose); }; _proto.componentWillUnmount = function componentWillUnmount() { this.disposeFunctions.forEach(function (fn) { return fn(); }); }; _proto.render = function render() { if (!this.state.visible || !this.state.condition) { return null; } var _this$props = this.props, forwardedRef = _this$props.forwardedRef, rest = (0, _objectWithoutPropertiesLoose2["default"])(_this$props, _excluded2); var compProps = (0, _extends2["default"])({}, rest, this.state.nodeCacheProps || {}, this.state.nodeProps || {}, { children: [], __id: this.props.componentId, ref: forwardedRef }); delete compProps.__inner__; if (this.hasChildren) { return engine.createElement(Comp, compProps, this.children); } return engine.createElement(Comp, compProps); }; return (0, _createClass2["default"])(LeafHoc, [{ key: "autoRepaintNode", get: function get() { return container === null || container === void 0 ? void 0 : container.autoRepaintNode; } }, { key: "hasChildren", get: function get() { if (!this.state.childrenInState) { return 'children' in this.props; } return true; } }, { key: "children", get: function get() { if (this.state.childrenInState) { return this.state.nodeChildren; } if (this.props.children && !Array.isArray(this.props.children)) { return [this.props.children]; } if (this.props.children && this.props.children.length) { return this.props.children; } return this.props.children; } }, { key: "leaf", get: function get() { var _this$props$_leaf; if ((_this$props$_leaf = this.props._leaf) !== null && _this$props$_leaf !== void 0 && _this$props$_leaf.isMock) { // 低代码组件作为一个整体更新,其内部的组件不需要监听相关事件 return undefined; } return getNode === null || getNode === void 0 ? void 0 : getNode(componentCacheId); } }]); }(Component); LeafHoc.displayName = schema.componentName; var LeafWrapper = forwardRef(function (props, ref) { return createElement(LeafHoc, (0, _extends2["default"])({}, props, { forwardedRef: ref })); }); LeafWrapper = (0, _lowcodeUtils.cloneEnumerableProperty)(LeafWrapper, Comp); LeafWrapper.displayName = Comp.displayName; cache.component.set(componentCacheId, { LeafWrapper: LeafWrapper, Comp: Comp }); return LeafWrapper; }