Command Pattern
HTML
<ul data-menu-bar>
<li data-command="Apple">apple</li>
<li data-command="Banana">banana</li>
<li data-command="Undo">undo</li>
<li data-command="Redo">redo</li>
</ul>
<ol data-output><ol>
JavaScript
var outputList = document.querySelector('[data-output]');
/**
* commands is a map of command objects.
*/
var commands = {
Undo: function () {
commandManager.invokeCommand(this);
},
Redo: function () {
commandManager.invokeCommand(this);
}
}
/**
* manages two lists: a history list and a redolist, each of which
* contains command objects: those which have run are in the history list;
* those which have been 'undone' are in the redo list.
*/
var commandManager = {
history: [],
redoList: [],
invokeCommand: function (command) {
// undo command
if (command instanceof commands.Undo) {
if (this.history.length > 0) {
var command = this.history.pop();
command.undoIt();
this.redoList.push(command);
} else {
alert("cannot undo. no commands in history");
}
return;
// redo command
} else if (command instanceof commands.Redo) {
if (this.redoList.length > 0) {
var command = this.redoList.pop();
command.doIt();
this.history.push(command);
} else {
alert("cannot redo. no commands in redo list");
}
return;
// normal commands
} else {
command.doIt();
this.history.push(command);
// clear redo list
this.redoList = [];
}
}
}
/*
*
* @classs
*/
function Apple() {
this.name = "apple";
commandManager.invokeCommand(this);
}
Apple.prototype = {
doIt: function () {
var newDiv = document.createElement("li");
var newContent = document.createTextNode("apple");
newDiv.appendChild(newContent);
outputList.appendChild(newDiv);
},
undoIt: function () {
outputList.removeChild(outputList.childNodes[outputList.childNodes.length -...