123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- /**
- * @fileOverview
- *
- * 历史管理
- *
- * @author: techird
- * @copyright: Baidu FEX, 2014
- */
- define(function(require, exports, module) {
- var jsonDiff = require('../tool/jsondiff');
- 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;
- });
|