import { AnyFun } from "queenjs/typing"; import { EditorModule } from "../../module"; import { Action, HistoryController } from "./HistoryController"; import { get } from "lodash"; export class HistoryCtrl { history: HistoryController; historyActionDoing = false; historyCombine = false; safeList = ["layout.size"]; constructor(protected module: EditorModule, historyTotal = 50) { this.history = new HistoryController(); this.history.state.maxLen = historyTotal; } record( root: any, type: Action["type"], paths: string[], value: any, oldValue: any ) { if (this.historyActionDoing) { if ( type === "set" && !this.safeList.some((str) => paths.slice(0, -1).join(".").includes(str)) ) { const parent = paths.length > 1 ? get(root, paths.slice(0, -1)) : root; if (parent instanceof Array) { console.warn( `操作警告[set:${paths.join( "." )}],应将数组整体替换赋值,不要操作原数组对象` ); } } const action = new Action(type, root, paths.join("."), value, oldValue); this.history.record(action, { combine: this.historyCombine }); } } bindActions(actNames: string[]) { const actions: any = this.module.actions; actNames.forEach((actName) => { const action = actions[actName]; actions[actName] = this.proxyAction.bind(this, action); }); } async proxyAction(action: AnyFun, ...args: any[]) { const { history } = this; if (this.historyActionDoing) { return await action(...args); } try { this.historyActionDoing = true; await action(...args); history.submit(); } catch (error) { console.error(error); history.cacheGroupAction.undo(); history.cacheGroupAction.actions = []; } finally { this.historyActionDoing = false; } } }