mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-17 22:08:25 +08:00
155 lines
3.8 KiB
JavaScript
155 lines
3.8 KiB
JavaScript
import { copyRenderTree, simpleDeepClone, nextTick } from '../../utils'
|
|
|
|
// 命令类
|
|
class Command {
|
|
// 构造函数
|
|
constructor(opt = {}) {
|
|
this.opt = opt
|
|
this.mindMap = opt.mindMap
|
|
this.commands = {}
|
|
this.history = []
|
|
this.activeHistoryIndex = 0
|
|
// 注册快捷键
|
|
this.registerShortcutKeys()
|
|
this.addHistory = nextTick(this.addHistory, this)
|
|
}
|
|
|
|
// 清空历史数据
|
|
clearHistory() {
|
|
this.history = []
|
|
this.activeHistoryIndex = 0
|
|
this.mindMap.emit('back_forward', 0, 0)
|
|
}
|
|
|
|
// 注册快捷键
|
|
registerShortcutKeys() {
|
|
this.mindMap.keyCommand.addShortcut('Control+z', () => {
|
|
this.mindMap.execCommand('BACK')
|
|
})
|
|
this.mindMap.keyCommand.addShortcut('Control+y', () => {
|
|
this.mindMap.execCommand('FORWARD')
|
|
})
|
|
}
|
|
|
|
// 执行命令
|
|
exec(name, ...args) {
|
|
if (this.commands[name]) {
|
|
this.commands[name].forEach(fn => {
|
|
fn(...args)
|
|
})
|
|
if (['BACK', 'FORWARD', 'SET_NODE_ACTIVE', 'CLEAR_ACTIVE_NODE'].includes(name)) {
|
|
return
|
|
}
|
|
this.addHistory()
|
|
}
|
|
}
|
|
|
|
// 添加命令
|
|
add(name, fn) {
|
|
if (this.commands[name]) {
|
|
this.commands[name].push(fn)
|
|
} else {
|
|
this.commands[name] = [fn]
|
|
}
|
|
}
|
|
|
|
// 移除命令
|
|
remove(name, fn) {
|
|
if (!this.commands[name]) {
|
|
return
|
|
}
|
|
if (!fn) {
|
|
this.commands[name] = []
|
|
delete this.commands[name]
|
|
} else {
|
|
let index = this.commands[name].find(item => {
|
|
return item === fn
|
|
})
|
|
if (index !== -1) {
|
|
this.commands[name].splice(index, 1)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 添加回退数据
|
|
addHistory() {
|
|
if (this.mindMap.opt.readonly) {
|
|
return
|
|
}
|
|
let data = this.getCopyData()
|
|
// 此次数据和上次一样则不重复添加
|
|
if (this.history.length > 0 && JSON.stringify(this.history[this.history.length - 1]) === JSON.stringify(data)) {
|
|
return
|
|
}
|
|
// 删除当前历史指针后面的数据
|
|
this.history = this.history.slice(0, this.activeHistoryIndex + 1)
|
|
this.history.push(simpleDeepClone(data))
|
|
// 历史记录数超过最大数量
|
|
if (this.history.length > this.mindMap.opt.maxHistoryCount) {
|
|
this.history.shift()
|
|
}
|
|
this.activeHistoryIndex = this.history.length - 1
|
|
this.mindMap.emit('data_change', this.removeDataUid(data))
|
|
this.mindMap.emit(
|
|
'back_forward',
|
|
this.activeHistoryIndex,
|
|
this.history.length
|
|
)
|
|
}
|
|
|
|
// 回退
|
|
back(step = 1) {
|
|
if (this.mindMap.opt.readonly) {
|
|
return
|
|
}
|
|
if (this.activeHistoryIndex - step >= 0) {
|
|
this.activeHistoryIndex -= step
|
|
this.mindMap.emit(
|
|
'back_forward',
|
|
this.activeHistoryIndex,
|
|
this.history.length
|
|
)
|
|
let data = simpleDeepClone(this.history[this.activeHistoryIndex])
|
|
this.mindMap.emit('data_change', this.removeDataUid(data))
|
|
return data
|
|
}
|
|
}
|
|
|
|
// 前进
|
|
forward(step = 1) {
|
|
if (this.mindMap.opt.readonly) {
|
|
return
|
|
}
|
|
let len = this.history.length
|
|
if (this.activeHistoryIndex + step <= len - 1) {
|
|
this.activeHistoryIndex += step
|
|
this.mindMap.emit('back_forward', this.activeHistoryIndex, this.history.length)
|
|
let data = simpleDeepClone(this.history[this.activeHistoryIndex])
|
|
this.mindMap.emit('data_change', this.removeDataUid(data))
|
|
return data
|
|
}
|
|
}
|
|
|
|
// 获取渲染树数据副本
|
|
getCopyData() {
|
|
return copyRenderTree({}, this.mindMap.renderer.renderTree, true)
|
|
}
|
|
|
|
// 移除节点数据中的uid
|
|
removeDataUid(data) {
|
|
data = simpleDeepClone(data)
|
|
let walk = (root) => {
|
|
delete root.data.uid
|
|
if (root.children && root.children.length > 0) {
|
|
root.children.forEach((item) => {
|
|
walk(item)
|
|
})
|
|
}
|
|
}
|
|
walk(data)
|
|
return data
|
|
}
|
|
}
|
|
|
|
export default Command
|