vue-kityminder-ggg
Version:
百度脑图
132 lines (115 loc) • 3.46 kB
JavaScript
/**
* @fileOverview
*
* 历史管理
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
define(function(require, exports, module) {
var jsonDiff = require('../tool/jsondiff').default;
function HistoryRuntime() {
var minder = this.minder;
var hotbox = this.hotbox;
var MAX_HISTORY = 100;
var lastSnap;
var patchLock;
var undoDiffs;
var redoDiffs;
function reset() {
undoDiffs = [];
redoDiffs = [];
lastSnap = minder.exportJson();
}
function makeUndoDiff() {
var headSnap = minder.exportJson();
var diff = jsonDiff(headSnap, lastSnap);
if (diff.length) {
undoDiffs.push(diff);
while (undoDiffs.length > MAX_HISTORY) {
undoDiffs.shift();
}
lastSnap = headSnap;
return true;
}
}
function makeRedoDiff() {
var revertSnap = minder.exportJson();
redoDiffs.push(jsonDiff(revertSnap, lastSnap));
lastSnap = revertSnap;
}
function undo() {
patchLock = true;
var undoDiff = undoDiffs.pop();
if (undoDiff) {
minder.applyPatches(undoDiff);
makeRedoDiff();
}
patchLock = false;
}
function redo() {
patchLock = true;
var redoDiff = redoDiffs.pop();
if (redoDiff) {
minder.applyPatches(redoDiff);
makeUndoDiff();
}
patchLock = false;
}
function changed() {
if (patchLock) return;
if (makeUndoDiff()) redoDiffs = [];
}
function hasUndo() {
return !!undoDiffs.length;
}
function hasRedo() {
return !!redoDiffs.length;
}
function updateSelection(e) {
if (!patchLock) return;
var patch = e.patch;
switch (patch.express) {
case 'node.add':
minder.select(patch.node.getChild(patch.index), true);
break;
case 'node.remove':
case 'data.replace':
case 'data.remove':
case 'data.add':
minder.select(patch.node, true);
break;
}
}
this.history = {
reset: reset,
undo: undo,
redo: redo,
hasUndo: hasUndo,
hasRedo: hasRedo
};
reset();
minder.on('contentchange', changed);
minder.on('import', reset);
minder.on('patch', updateSelection);
var main = hotbox.state('main');
main.button({
position: 'top',
label: '撤销',
key: 'Ctrl + Z',
enable: hasUndo,
action: undo,
next: 'idle'
});
main.button({
position: 'top',
label: '重做',
key: 'Ctrl + Y',
enable: hasRedo,
action: redo,
next: 'idle'
});
}
window.diff = jsonDiff;
return module.exports = HistoryRuntime;
});