diff --git a/app/app.js b/app/app.js index 0f60ce4..d4004cb 100644 --- a/app/app.js +++ b/app/app.js @@ -6,7 +6,7 @@ debugMode: false }; - var commandHandlers = {}; + var appModules = []; var runObservers = []; app.di = new Container(); @@ -23,15 +23,28 @@ return this.di.resolve(name); }; + app.compose = function (module) { + appModules.push(module); + }; + app.run = function(observer) { runObservers.push(observer); }; app.bootstrap = function(rootViewElement) { this.rootViewElement = rootViewElement; + initializeModules(); invokeRunObservers(); }; + function initializeModules() { + appModules.forEach(function(m) { + if(is.aFunction(m)) { + m(); + } + }); + } + function invokeRunObservers() { runObservers.forEach(function(o){ o(); }); } diff --git a/app/controllers.js b/app/controllers.js index fd7f94f..be7a327 100644 --- a/app/controllers.js +++ b/app/controllers.js @@ -1,78 +1,85 @@ -(function(app, is){ +app.compose(function() { - app.controller('expressionInputCtrl', { - $dispatcher:null, - onViewAttached: function () { - var d = this.$dispatcher; + app.controller('expressionInputCtrl', function (){ + var dispatcher = app.component('dispatcher'); - var self = this; - self.history =[]; - self.historyIndex = 0; + return { + onViewAttached: function () { + var d = dispatcher; - this.viewElement.focus(); - - this.viewElement.addEventListener('keyup', function (args) { - var inpt = args.srcElement; - - if (args.keyCode != 13) { - return; - } - - // Enter - d.dispatch(inpt.value); - self.history.unshift(inpt.value); + var self = this; + self.history =[]; self.historyIndex = 0; - inpt.value = ''; - }); - this.viewElement.addEventListener('keydown', function(args){ - if(args.keyCode == 38) { + this.viewElement.focus(); - if (self.history.length > self.historyIndex) { // up - args.srcElement.value = self.history[self.historyIndex++]; + this.viewElement.addEventListener('keyup', function (args) { + var inpt = args.srcElement; + if (args.keyCode != 13) { + return; } - args.preventDefault(); - return; - } + // Enter + d.dispatch(inpt.value); + self.history.unshift(inpt.value); + self.historyIndex = 0; + inpt.value = ''; + }); - if(args.keyCode == 40) { + this.viewElement.addEventListener('keydown', function(args){ + if(args.keyCode == 38) { - if(self.historyIndex > 0) { // up - args.srcElement.value = self.history[--self.historyIndex]; + if (self.history.length > self.historyIndex) { // up + args.srcElement.value = self.history[self.historyIndex++]; + + } + + args.preventDefault(); + return; } - args.preventDefault(); - return; - } - }) + if(args.keyCode == 40) { + + if(self.historyIndex > 0) { // up + args.srcElement.value = self.history[--self.historyIndex]; + } + + args.preventDefault(); + return; + } + }) + } } }); - var resultViewController = { - $html: null, - clear: function (){ - this.viewElement.innerHTML = ''; - }, - onViewAttached: function(el) { - var r = 1; - }, - display: function ( model) { - var view = app.buildViewFor(model); + app.controller('resultViewCtrl', function() { + var html = app.component('html'); - var vw = this.viewElement; - if(vw.childNodes.length == 0) { - vw.appendChild(view); - } - else { - vw.insertBefore(view, vw.childNodes[0]); - } - } - }; + var resultViewController = { + $html: null, + clear: function (){ + this.viewElement.innerHTML = ''; + }, + onViewAttached: function(el) { + var r = 1; + }, + display: function ( model) { + var view = app.buildViewFor(model); - app.component('resultView', resultViewController); - app.controller('resultViewCtrl', resultViewController); + var vw = this.viewElement; + if(vw.childNodes.length == 0) { + vw.appendChild(view); + } + else { + vw.insertBefore(view, vw.childNodes[0]); + } + } + }; + + + return resultViewController; + }); app.controller('configPanelCtrl', { onViewAttached: function (){ @@ -84,4 +91,6 @@ } }); -})(window.app, window.is); +}); + + diff --git a/app/dispatcher.js b/app/dispatcher.js index c1140c1..3ce19a4 100644 --- a/app/dispatcher.js +++ b/app/dispatcher.js @@ -1,87 +1,89 @@ -(function(app, is){ +app.compose(function() { + app.component('dispatcher', function() { + var handlers = []; + var is = app.component('is'); + var resultView = app.controller('resultViewCtrl'); - var handlers = []; + var dispatcher = { + dispatch: function(rawInput) { + var input = rawInput.trim(); + var handler = this.findHandler(input); - var dispatcher = { - $resultView:null, - dispatch: function(rawInput) { - var input = rawInput.trim(); - var handler = this.findHandler(input); - if(handler != null) { + if(handler != null) { - if(app.debugMode) { - this.invokeHandler(input, handler); - } else { - try { + if(app.debugMode) { this.invokeHandler(input, handler); - } catch (e) { - this.displayCommandError(input, "Error: " + e); + } else { + try { + this.invokeHandler(input, handler); + } catch (e) { + this.displayCommandError(input, "Error: " + e); + } } } - } - else { - this.displayCommandError(input, "Unknown expression: " + input.trim()); - } - - // app.command('dispatchInput').execute({input:input}); - }, - command: function(cmd, handler) { - var h = this.createHandler(cmd, handler); - if(h == null){ - console.warn('unexpected set of arguments: ', Array.prototype.splice.call(arguments)); - return; - } - - if(!is.aFunction(h.canHandle)) { - console.warn('handler is missing "canHandle" function. registration denied.'); - return; - } - - if(!is.aFunction(h.handle)) { - console.warn('handler is missing "handle" function. registration denied.'); - return; - } - - app.di.resolveProperties(h); - handlers.push(h); - }, - createHandler: function(cmd, handler) { - if(is.plainObject(cmd)) { - return cmd; - } - - if(is.string(cmd)) { - return { canHandle: function (input) { return input === cmd; }, handle: handler }; - } - - return null; - }, - findHandler: function (input) { - var i= 0, h; - for(i;i>/.test(expr.sign) ? 'shiftExpressionView' : 'binaryExpressionView'; - var html = document.getElementById(templateId).innerHTML; - var el = $html.element(html, expr); + var htmlTpl = document.getElementById(templateId).innerHTML; + var el = html.element(htmlTpl, expr); colorizeBits(el); return el; @@ -26,11 +23,9 @@ }); app.modelView(app.models.BitwiseNumbers, { - $html:null, - $calc:null, renderView: function(model) { var maxLen = getBinaryLength(model.numbers); - var table = this.$html.element('
'); + var table = html.element('
'); if(app.emphasizeBytes) { if(maxLen % 8 != 0) { @@ -58,24 +53,21 @@ }); app.modelView(app.models.HelpResult, { - $html: null, renderView: function(model) { var template = document.getElementById('helpView').innerHTML; - return this.$html.element(template); + return html.element(template); } }); app.modelView(app.models.ErrorResult, { - $html: null, renderView: function(model) { - return this.$html.element('
{message}
', model); + return html.element('
{message}
', model); } }); app.modelView(app.models.DisplayResult, { - $html: null, renderView: function(model) { - var resultView = this.$html.element(document.getElementById('resultView').innerHTML, model); + var resultView = html.element(document.getElementById('resultView').innerHTML, model); var contentView = app.buildViewFor(model.content); resultView.querySelector('.content').appendChild(contentView); @@ -107,6 +99,5 @@ .replace(/1/g, '1'); }); } - -})(window.app); +}); diff --git a/components/controllersFeature.js b/components/controllersFeature.js index a7f2559..15e4b8c 100644 --- a/components/controllersFeature.js +++ b/components/controllersFeature.js @@ -1,26 +1,40 @@ -(function(app) { +(function(app, should, Container) { - app.controller = function(name, inst) { - addControllerMixin(inst); - this.di.register(name, inst); + var controllerDi = app.di; // TODO: Compbine + + app.controller = function(name, instOrFactory) { + + should.beString(name, "name"); + + if(instOrFactory == null) { + return controllerDi.resolve(name); + } + + var reg = new Container.Registration(instOrFactory); + + reg.onFirstTimeResolve = function (inst) { + addControllerMixin(inst); + }; + + controllerDi.register(name, reg); }; - function addControllerMixin(component) { - component.attachView = function(viewElement) { + function addControllerMixin(ctrl) { + ctrl.attachView = function(viewElement) { this.viewElement = viewElement; - if(typeof component.onViewAttached == 'function') { - component.onViewAttached(viewElement); + if(typeof ctrl.onViewAttached == 'function') { + ctrl.onViewAttached(viewElement); } }; - component.detachView = function() { + ctrl.detachView = function() { this.viewElement = null; - if(typeof component.onViewDetached == 'function') { - component.onViewDetached(viewElement); + if(typeof ctrl.onViewDetached == 'function') { + ctrl.onViewDetached(viewElement); } }; } @@ -29,7 +43,7 @@ attachControllers(app.rootViewElement, app.di); }); - function attachControllers(rootViewElement, di) { + function attachControllers(rootViewElement) { var elements = rootViewElement.querySelectorAll('[data-controller]'), i = 0, l = elements.length, ctrlName, @@ -38,7 +52,7 @@ for(;i 0) { + if(arr[i] === item) { + return true; + } + } + + return false; + } + window.Container = Container; -})(); +})(window.is); diff --git a/components/is.js b/components/is.js index c1bc96c..38971e5 100644 --- a/components/is.js +++ b/components/is.js @@ -22,6 +22,10 @@ htmlElement: function(obj) { return obj instanceof HtmlElement; + }, + + array: function(obj) { + return obj instanceof Array; } }; })(); diff --git a/index.html b/index.html index 4e01309..6ea53a0 100644 --- a/index.html +++ b/index.html @@ -41,7 +41,7 @@ -
+
- - - \ No newline at end of file