Skip to content

Instantly share code, notes, and snippets.

@nyteshade
Last active May 4, 2017 22:51
Show Gist options
  • Save nyteshade/ee838ba6c4571f6be878afc1d785565e to your computer and use it in GitHub Desktop.
Save nyteshade/ee838ba6c4571f6be878afc1d785565e to your computer and use it in GitHub Desktop.
Simple class in ES5 parlance that tracks code and its history of changes
// ES5
/**
* The Code "class" defines an object that represents a source code with
* a history of changes. Whenever its source property is assigned, the
* new value is pushed onto a stack of code. Whenever its source property
* is read, the latest iteration of the code is returned as a string.
*
* @method Code
*
* @param {String} source a string of source code to intialize the object with
*/
function Code(source) {
if (source) {
this.source = source;
}
}
Object.defineProperties(Code.prototype, {
/**
* The source property is overloaded with a custom getter and setter. When
* read, it returns the last item in the history array. When set, it appends
* a new item as the last in the history array. This allows subsequent
* plugins using this Code instance to see changes, revert changes, and or
* manipulate code as necessary for its functionality.
*
* @type {String} source virtually represents a string of source code within
* the internal history object.
*/
source: {
/**
* The getter for the source property; when accessed the latest iteration
* of the source code is returned.
*
* @method
*
* @return {String} the latest bit of source code from the history or null
*/
get: function() {
if (!this.history || !this.history.length) {
return null;
}
return this.history[this.history.length - 1];
},
/**
* The setter for the source property; when assigned, a new iteration of
* source code is pushed onto the history. Accessing source in a read
* fashion afterwards will return this new value until the next time a
* new bit is written.
*
* @method
*
* @param {String} sourcecode a new version of the source code to append
* to the history.
*/
set: function(sourcecode) {
if (!this.history) {
this.history = [];
}
this.history.push(sourcecode);
}
},
/** @type {String[]} history an array of strings denoting source code */
history: { value: [] },
/**
* Undo removes the last item in the history list and returns it. Subsequent
* reads from this.source will return the item in the history prior to this
* most recent before this call or null if the removed item was the only item
* in the list.
*
* @method
*
* @return {String} the most recent bit of code in the history as it was
* removed.
*/
undo: {
value: function() {
return this.history.pop()
}
},
/**
* A function that resets the history to its first element. If there are
* no items in the history, this function is a no-op.
*
* @function reset
*
* @return {Code} this is returned to allow for inlining.
*/
reset: {
value: function() {
if (this.history.length) {
this.history = this.history.splice(1, this.history.length - 1);
}
return this;
}
},
/**
* Returns this.source whenever converted to a String
*
* @return {String} a direct reference to the latest value of this.source
*/
toString: {
value: function() {
return this.source;
}
}
});
module.exports = Code;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment