"input > .text": "textChange",
"blur > .text": "render", // Because the model shouldn't update the view during active editing, add a re-render at the end
"keydown > .text": "keydown",
+ // "Shortcut(ID, TEXT, DEFAULT KEYBINDING) SELECTOR": "ACTION"
'Shortcut("combinePrevious", "Combine an item with the previous item", "backspace") > .text': "combinePrevious",
'Shortcut("combineNext", "Combine an item with the next item", "del") > .text': "combineNext",
'Shortcut("next", "Next", "down") > .text': 'focusNext',
];
+BaseAction = function() {};
+BaseAction.prototype= {
+ apply: function() {},
+ rewind: function() {},
+ reapply: function() { return this.apply.apply(this, arguments); },
+};
+
+Actions = {};
+
+Actions.AppendWords = function(array, word) {
+ this.array = array;
+ this.word = word;
+};
+Actions.AppendWords.prototype = _.extend(new BaseAction(), {
+ apply: function() {
+ this.array.push(this.word);
+ },
+ rewind: function() {
+ var a = this.array.pop();
+ if (a !== this.word) {
+ throw "Rewind faiiiiiled :(";
+ }
+ },
+});
+
/**
* @depend ../views/todo.js
* @depend ../models/flowyDoc.js
* @depend ../models/todo.js
* @depend ../library/viewShortcuts.js
* @depend ../views/testTodos.js
+ * @depend ../actions.js
*/
var todos = new FlowyDocModel({
});
Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous', 'left', 'right'] });
this.views = {}; // A list of views for each element in the collection
+ this.history = [];
+ this.history.redo = [];
this.list.fetch();
this.render();
},
this.renderTodo(todo, { rerender: true }); // Don't remove existing view since it's still valid.
}
},
+ act: function(action) {
+ action.apply();
+ this.history.push(action);
+ this.history.redo = [];
+ },
+ undo: function() {
+ var action = this.history.pop();
+ if (!action) throw "Rewind called with empty history stack";
+ action.rewind();
+ this.history.redo.push(action);
+ },
+ redo: function() {
+ var action = this.history.redo.pop();
+ if (!action) throw "Replay called with empty redo stack";
+ action.reapply();
+ this.history.push(action);
+ },
toggleShortcuts: function() {
this.$(".shortcuts").toggle();
return false;
},
});
-// DEBUGGING
-window.Backbone = Backbone;
-window.Shortcut = Shortcut;
-window.AppView = AppView;
-
/**
* @depend views/app.js
*/
$(function() {
var flowyView = new AppView();
+ window.Flowy = flowyView;
+
+ // DEBUGGING
+ window.Backbone = Backbone;
+ window.Shortcut = Shortcut;
+ window.Actions = Actions;
});
+
});
"input > .text": "textChange",
"blur > .text": "render", // Because the model shouldn't update the view during active editing, add a re-render at the end
"keydown > .text": "keydown",
+ // "Shortcut(ID, TEXT, DEFAULT KEYBINDING) SELECTOR": "ACTION"
'Shortcut("combinePrevious", "Combine an item with the previous item", "backspace") > .text': "combinePrevious",
'Shortcut("combineNext", "Combine an item with the next item", "del") > .text': "combineNext",
'Shortcut("next", "Next", "down") > .text': 'focusNext',
];
+BaseAction = function() {};
+BaseAction.prototype= {
+ apply: function() {},
+ rewind: function() {},
+ reapply: function() { return this.apply.apply(this, arguments); },
+};
+
+Actions = {};
+
+Actions.AppendWords = function(array, word) {
+ this.array = array;
+ this.word = word;
+};
+Actions.AppendWords.prototype = _.extend(new BaseAction(), {
+ apply: function() {
+ this.array.push(this.word);
+ },
+ rewind: function() {
+ var a = this.array.pop();
+ if (a !== this.word) {
+ throw "Rewind faiiiiiled :(";
+ }
+ },
+});
+
/**
* @depend ../views/todo.js
* @depend ../models/flowyDoc.js
* @depend ../models/todo.js
* @depend ../library/viewShortcuts.js
* @depend ../views/testTodos.js
+ * @depend ../actions.js
*/
var todos = new FlowyDocModel({
});
Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous', 'left', 'right'] });
this.views = {}; // A list of views for each element in the collection
+ this.history = [];
+ this.history.redo = [];
this.list.fetch();
this.render();
},
this.renderTodo(todo, { rerender: true }); // Don't remove existing view since it's still valid.
}
},
+ act: function(action) {
+ action.apply();
+ this.history.push(action);
+ this.history.redo = [];
+ },
+ undo: function() {
+ var action = this.history.pop();
+ if (!action) throw "Rewind called with empty history stack";
+ action.rewind();
+ this.history.redo.push(action);
+ },
+ redo: function() {
+ var action = this.history.redo.pop();
+ if (!action) throw "Replay called with empty redo stack";
+ action.reapply();
+ this.history.push(action);
+ },
toggleShortcuts: function() {
this.$(".shortcuts").toggle();
return false;
},
});
-// DEBUGGING
-window.Backbone = Backbone;
-window.Shortcut = Shortcut;
-window.AppView = AppView;
-
/**
* @depend views/app.js
*/
$(function() {
var flowyView = new AppView();
+ window.Flowy = flowyView;
+
+ // DEBUGGING
+ window.Backbone = Backbone;
+ window.Shortcut = Shortcut;
+ window.Actions = Actions;
});
+
--- /dev/null
+BaseAction = function() {};
+BaseAction.prototype= {
+ apply: function() {},
+ rewind: function() {},
+ reapply: function() { return this.apply.apply(this, arguments); },
+};
+
+Actions = {};
+
+Actions.AppendWords = function(array, word) {
+ this.array = array;
+ this.word = word;
+};
+Actions.AppendWords.prototype = _.extend(new BaseAction(), {
+ apply: function() {
+ this.array.push(this.word);
+ },
+ rewind: function() {
+ var a = this.array.pop();
+ if (a !== this.word) {
+ throw "Rewind faiiiiiled :(";
+ }
+ },
+});
$(function() {
var flowyView = new AppView();
+ window.Flowy = flowyView;
+
+ // DEBUGGING
+ window.Backbone = Backbone;
+ window.Shortcut = Shortcut;
+ window.Actions = Actions;
});
+
* @depend ../models/todo.js
* @depend ../library/viewShortcuts.js
* @depend ../views/testTodos.js
+ * @depend ../actions.js
*/
var todos = new FlowyDocModel({
});
Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous', 'left', 'right'] });
this.views = {}; // A list of views for each element in the collection
+ this.history = [];
+ this.history.redo = [];
this.list.fetch();
this.render();
},
this.renderTodo(todo, { rerender: true }); // Don't remove existing view since it's still valid.
}
},
+ act: function(action) {
+ action.apply();
+ this.history.push(action);
+ this.history.redo = [];
+ },
+ undo: function() {
+ var action = this.history.pop();
+ if (!action) throw "Rewind called with empty history stack";
+ action.rewind();
+ this.history.redo.push(action);
+ },
+ redo: function() {
+ var action = this.history.redo.pop();
+ if (!action) throw "Replay called with empty redo stack";
+ action.reapply();
+ this.history.push(action);
+ },
toggleShortcuts: function() {
this.$(".shortcuts").toggle();
return false;
this.list.each(this.addOne, this);
},
});
-
-// DEBUGGING
-window.Backbone = Backbone;
-window.Shortcut = Shortcut;
-window.AppView = AppView;
"input > .text": "textChange",
"blur > .text": "render", // Because the model shouldn't update the view during active editing, add a re-render at the end
"keydown > .text": "keydown",
+ // "Shortcut(ID, TEXT, DEFAULT KEYBINDING) SELECTOR": "ACTION"
'Shortcut("combinePrevious", "Combine an item with the previous item", "backspace") > .text': "combinePrevious",
'Shortcut("combineNext", "Combine an item with the next item", "del") > .text': "combineNext",
'Shortcut("next", "Next", "down") > .text': 'focusNext',