Implemented historical commands

This commit is contained in:
Borys Levytskyi
2015-04-03 19:31:57 +03:00
parent 8e5be22fe3
commit 022c65635c
12 changed files with 148 additions and 122 deletions

View File

@@ -1,8 +1,9 @@
(function (should, commandr, bindr, Container) { (function (should, Container) {
var app = { var app = {
views: {}, views: {},
models: {} models: {},
debugMode: false
}; };
var commandHandlers = {}; var commandHandlers = {};
@@ -22,35 +23,6 @@
return this.di.resolve(name); return this.di.resolve(name);
}; };
app.service = app.component;
// TODO: introduce command feature
app.command = function(name, handler) {
var cmd = commandHandlers[name];
if(cmd == null) {
cmd = commandHandlers[name] = new commandr.Command(name);
}
if(typeof handler == "function") {
cmd.subscribe(handler);
}
if (typeof handler == "object") {
if(typeof handler.execute != "function"){
console.warn('Given handler is an object, but doesn\'t have "execute" function');
return cmd;
}
this.di.resolveProperties(handler);
cmd.subscribe(handler.execute.bind(handler));
}
return cmd;
};
app.run = function(observer) { app.run = function(observer) {
runObservers.push(observer); runObservers.push(observer);
}; };
@@ -66,5 +38,4 @@
window.app = app; window.app = app;
})(window.should, window.Container);
})(window.should, window.commandr, window.bindr, window.Container);

View File

@@ -1,23 +1,21 @@
(function(app, should){ (function(app, should){
var calc = {}; app.component('calc', {
calc.numberOfBits = function(num) { numberOfBits: function (num) {
should.bePositiveInteger(num); should.bePositiveInteger(num);
return Math.floor(Math.log(num) / Math.log(2)) + 1; return Math.floor(Math.log(num) / Math.log(2)) + 1;
}; },
calc.maxNumberOfBits = function (arr) { maxNumberOfBits: function (arr) {
var counts = [], num; var counts = [], num;
for(var i=0;i<arr.length; i++) for (var i = 0; i < arr.length; i++) {
{
num = arr[i]; num = arr[i];
counts.push(this.numberOfBits(num)); counts.push(this.numberOfBits(num));
} }
return Math.max.apply(null, counts); return Math.max.apply(null, counts);
}; }
});
app.service('calc', calc);
})(window.app, window.should); })(window.app, window.should);

View File

@@ -2,7 +2,7 @@
var twoOperandsRegex = /^(\d+)\s*(<<|>>|\||\&|\^)\s*(\d+)$/; var twoOperandsRegex = /^(\d+)\s*(<<|>>|\||\&|\^)\s*(\d+)$/;
var numbersList = /^((\d*)+\s?)+$/; var numbersList = /^((\d*)+\s?)+$/;
app.service('expression', { app.component('expression', {
canParse: function(string) { canParse: function(string) {
return twoOperandsRegex.test(string) || numbersList.test(string); return twoOperandsRegex.test(string) || numbersList.test(string);
}, },

View File

@@ -1,6 +1,6 @@
(function(should, app){ (function(should, app){
app.service("formatter", { app.component("formatter", {
toBinaryString: function(num, totalLength) { toBinaryString: function(num, totalLength) {
var binaryStr = num.toString(2), var binaryStr = num.toString(2),

View File

@@ -4,20 +4,54 @@
$dispatcher:null, $dispatcher:null,
onViewAttached: function () { onViewAttached: function () {
var d = this.$dispatcher; var d = this.$dispatcher;
var self = this;
self.history =[];
self.historyIndex = 0;
this.viewElement.focus(); this.viewElement.focus();
this.viewElement.addEventListener('keyup', function (args) { this.viewElement.addEventListener('keyup', function (args) {
var inpt = args.srcElement;
if (args.keyCode != 13) { if (args.keyCode != 13) {
return; return;
} }
// Enter // Enter
d.dispatch(args.srcElement.value); d.dispatch(inpt.value);
args.srcElement.value = ''; self.history.unshift(inpt.value);
self.historyIndex = 0;
inpt.value = '';
}); });
this.viewElement.addEventListener('keydown', function(args){
console.log(args.keyCode);
if(args.keyCode == 38) {
if (self.history.length > self.historyIndex) { // up
args.srcElement.value = self.history[self.historyIndex++];
}
args.preventDefault();
return;
}
if(args.keyCode == 40) {
if(self.historyIndex > 0) { // up
args.srcElement.value = self.history[--self.historyIndex];
}
args.preventDefault();
return;
}
})
} }
}); });
app.service('resultView', { var resultViewController = {
$html: null, $html: null,
clear: function (){ clear: function (){
this.viewElement.innerHTML = ''; this.viewElement.innerHTML = '';
@@ -36,8 +70,9 @@
vw.insertBefore(view, vw.childNodes[0]); vw.insertBefore(view, vw.childNodes[0]);
} }
} }
}); };
app.controller('resultViewCtrl', app.service('resultView')); app.component('resultView', resultViewController);
app.controller('resultViewCtrl', resultViewController);
})(window.app, window.is); })(window.app, window.is);

View File

@@ -4,14 +4,13 @@
var dispatcher = { var dispatcher = {
$resultView:null, $resultView:null,
debug:true,
dispatch: function(rawInput) { dispatch: function(rawInput) {
var input = rawInput.trim(); var input = rawInput.trim();
var handler = this.findHandler(input); var handler = this.findHandler(input);
if(handler != null) { if(handler != null) {
if(this.debug) { if(app.debugMode) {
this.invokeHandler(input, handler); this.invokeHandler(input, handler);
} else { } else {
try { try {
@@ -83,6 +82,6 @@
app.get('resultView').clear(); app.get('resultView').clear();
}); });
app.service('dispatcher', dispatcher); app.component('dispatcher', dispatcher);
})(window.app, window.is); })(window.app, window.is);

View File

@@ -1,6 +1,6 @@
(function(app, HtmlBuilder){ (function(app, HtmlBuilder){
app.service('html', { app.component('html', {
builder: function () { builder: function () {
return new HtmlBuilder(); return new HtmlBuilder();
}, },

View File

@@ -1,8 +1,8 @@
// Expression View // Expression View
(function(app) { (function(app) {
var formatter = app.service('formatter'); var formatter = app.component('formatter');
var calc = app.service('calc'); var calc = app.component('calc');
app.modelView(app.models.BitwiseOperation, { app.modelView(app.models.BitwiseOperation, {
$html:null, $html:null,

View File

@@ -1,31 +0,0 @@
(function(){
var commandr = {
};
function Command(name) {
this.name = name;
this.executionHandlers = [];
}
Command.prototype.execute = function (cmdArgs) {
cmdArgs = cmdArgs || {};
cmdArgs.commandHandled = false;
for(var i=0; i<this.executionHandlers.length; i++) {
this.executionHandlers[i](cmdArgs);
if(cmdArgs.commandHandled === true) {
return;
}
}
};
Command.prototype.subscribe = function (handler) {
this.executionHandlers.push(handler);
// TODO: unsubcribe
};
commandr.Command = Command;
window.commandr = commandr;
})();

View File

@@ -0,0 +1,52 @@
(function(app){
function Command(name) {
this.name = name;
this.executionHandlers = [];
}
Command.prototype.execute = function (cmdArgs) {
cmdArgs = cmdArgs || {};
cmdArgs.commandHandled = false;
for(var i=0; i<this.executionHandlers.length; i++) {
this.executionHandlers[i](cmdArgs);
if(cmdArgs.commandHandled === true) {
return;
}
}
};
Command.prototype.subscribe = function (handler) {
this.executionHandlers.push(handler);
// TODO: unsubcribe
};
app.commandHandlers = {};
app.command = function(name, handler) {
var cmd = this.commandHandlers[name];
if(cmd == null) {
cmd = this.commandHandlers[name] = new commandr.Command(name);
}
if(typeof handler == "function") {
cmd.subscribe(handler);
}
if (typeof handler == "object") {
if(typeof handler.execute != "function"){
console.warn('Given handler is an object, but doesn\'t have "execute" function');
return cmd;
}
this.di.resolveProperties(handler);
cmd.subscribe(handler.execute.bind(handler));
}
return cmd;
};
window.commandr = commandr;
})(window.app);

View File

@@ -1,4 +1,6 @@
(function(should){ // Problems: no check for the circular references
(function(){
function Container(store) { function Container(store) {
this.store = {}; this.store = {};
} }
@@ -12,7 +14,6 @@
return reg; return reg;
}; };
// TODO: Check for circular - dependencies
Container.prototype.resolve = function(name) { Container.prototype.resolve = function(name) {
var reg = this.store[name]; var reg = this.store[name];
if(reg == null) { if(reg == null) {
@@ -25,18 +26,21 @@
reg.resolved = inst; reg.resolved = inst;
} }
console.log(name + ' resolved', reg.resolved);
return reg.resolved; return reg.resolved;
}; };
Container.prototype.resolveProperties = function (instance) { Container.prototype.resolveProperties = function (instance) {
for(var property in instance) { for(var prop in instance) {
if(property[0] == '$' && instance[property] == null) { if(!instance.hasOwnProperty(prop)) {
var name = property.substr(1, property.length - 1); continue;
instance[property] = this.resolve(name); }
if(instance[property] == null) { if(prop[0] == '$' && instance[prop] == null) {
console.log('"' + property + '" property couldn\'t be resolved') var key = prop.substr(1, prop.length - 1);
instance[prop] = this.resolve(key);
if(instance[prop] == null) {
console.log('"' + prop + '" property couldn\'t be resolved')
} }
} }
} }

View File

@@ -5,12 +5,10 @@
<title></title> <title></title>
<script type="text/javascript" src="components/bindr.js"></script>
<script type="text/javascript" src="components/commandr.js"></script>
<script type="text/javascript" src="components/is.js"></script> <script type="text/javascript" src="components/is.js"></script>
<script type="text/javascript" src="components/should.js"></script> <script type="text/javascript" src="components/should.js"></script>
<script type="text/javascript" src="components/htmlBuilder.js"></script> <script type="text/javascript" src="components/htmlBuilder.js"></script>
<script type="text/javascript" src="components/container.js"></script> <script type="text/javascript" src="components/di.js"></script>
<script type="text/javascript" src="app/app.js"></script> <script type="text/javascript" src="app/app.js"></script>
<script type="text/javascript" src="components/controllersFeature.js"></script> <script type="text/javascript" src="components/controllersFeature.js"></script>