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 = {
views: {},
models: {}
models: {},
debugMode: false
};
var commandHandlers = {};
@@ -22,35 +23,6 @@
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) {
runObservers.push(observer);
};
@@ -66,5 +38,4 @@
window.app = app;
})(window.should, window.commandr, window.bindr, window.Container);
})(window.should, window.Container);

View File

@@ -1,23 +1,21 @@
(function(app, should){
var calc = {};
app.component('calc', {
calc.numberOfBits = function(num) {
should.bePositiveInteger(num);
return Math.floor(Math.log(num) / Math.log(2)) + 1;
};
numberOfBits: function (num) {
should.bePositiveInteger(num);
return Math.floor(Math.log(num) / Math.log(2)) + 1;
},
calc.maxNumberOfBits = function (arr) {
maxNumberOfBits: function (arr) {
var counts = [], num;
for(var i=0;i<arr.length; i++)
{
num = arr[i];
counts.push(this.numberOfBits(num));
var counts = [], num;
for (var i = 0; i < arr.length; i++) {
num = arr[i];
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);

View File

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

View File

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

View File

@@ -4,40 +4,75 @@
$dispatcher:null,
onViewAttached: function () {
var d = this.$dispatcher;
var self = this;
self.history =[];
self.historyIndex = 0;
this.viewElement.focus();
this.viewElement.addEventListener('keyup', function (args) {
var inpt = args.srcElement;
if (args.keyCode != 13) {
return;
}
// Enter
d.dispatch(args.srcElement.value);
args.srcElement.value = '';
d.dispatch(inpt.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', {
$html: null,
clear: function (){
this.viewElement.innerHTML = '';
},
onViewAttached: function(el) {
var r = 1;
},
display: function ( model) {
var view = app.buildViewFor(model);
var resultViewController = {
$html: null,
clear: function (){
this.viewElement.innerHTML = '';
},
onViewAttached: function(el) {
var r = 1;
},
display: function ( model) {
var view = app.buildViewFor(model);
var vw = this.viewElement;
if(vw.childNodes.length == 0) {
vw.appendChild(view);
}
else {
vw.insertBefore(view, vw.childNodes[0]);
}
}
});
var vw = this.viewElement;
if(vw.childNodes.length == 0) {
vw.appendChild(view);
}
else {
vw.insertBefore(view, vw.childNodes[0]);
}
}
};
app.controller('resultViewCtrl', app.service('resultView'));
app.component('resultView', resultViewController);
app.controller('resultViewCtrl', resultViewController);
})(window.app, window.is);

View File

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

View File

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

View File

@@ -1,8 +1,8 @@
// Expression View
(function(app) {
var formatter = app.service('formatter');
var calc = app.service('calc');
var formatter = app.component('formatter');
var calc = app.component('calc');
app.modelView(app.models.BitwiseOperation, {
$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) {
this.store = {};
}
@@ -12,7 +14,6 @@
return reg;
};
// TODO: Check for circular - dependencies
Container.prototype.resolve = function(name) {
var reg = this.store[name];
if(reg == null) {
@@ -25,18 +26,21 @@
reg.resolved = inst;
}
console.log(name + ' resolved', reg.resolved);
return reg.resolved;
};
Container.prototype.resolveProperties = function (instance) {
for(var property in instance) {
if(property[0] == '$' && instance[property] == null) {
var name = property.substr(1, property.length - 1);
instance[property] = this.resolve(name);
for(var prop in instance) {
if(!instance.hasOwnProperty(prop)) {
continue;
}
if(instance[property] == null) {
console.log('"' + property + '" property couldn\'t be resolved')
if(prop[0] == '$' && instance[prop] == null) {
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>
<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/should.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="components/controllersFeature.js"></script>