diff options
Diffstat (limited to 'js/codeq/navigation.js')
-rw-r--r-- | js/codeq/navigation.js | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/js/codeq/navigation.js b/js/codeq/navigation.js new file mode 100644 index 0000000..4445a3d --- /dev/null +++ b/js/codeq/navigation.js @@ -0,0 +1,104 @@ +/** + * Created by robert on 9/15/15. + */ +(function() { + codeq.makeStateMachine = function (def) { + var currState = null; + return { + 'transition': function (name) { + var newState = def[name]; + if (!newState) { + codeq.log.error('Cannot transition to state ' + name + ': it is not defined'); + return; + } + if (newState === currState) { + codeq.log.info('Will not transition between identical states: ' + name); + return; + } + if (currState !== null) currState.exit(); + currState = newState; + currState.enter.apply(currState, Array.prototype.slice.apply(arguments, [1])); + }, + 'destroy': function () { + if (currState !== null) currState.exit(); + currState = null; + }, + 'register': function (name, state) { + if (name in def) codeq.log.error('The state ' + name + ' is already registered, overriding'); + def[name] = state; + } + } + }; + + + //the global state machine is a bit different - so it'll be implemented here + var makeGlobalStateMachine = function (def) { + var currState = null; + var stateChangeFun = function historyStateChangeHandler() { + var historyState = History.getState(); + codeq.globalStateMachine.actualTransition.apply(codeq.globalStateMachine, $.merge([historyState.data.state] ,historyState.data.params)); + }; + History.Adapter.bind(window, 'statechange', stateChangeFun); + //prepare the history state change listener + return { + 'transition': function (name) { + var newState = def[name]; + if (!newState) { + codeq.log.error('Cannot transition to state ' + name + ': it is not defined'); + return; + } + if (newState === currState) { + codeq.log.info('Will not transition between identical states: ' + name); + return; + } + + if(History.getState().data.state === name) codeq.globalStateMachine.actualTransition.apply(codeq.globalStateMachine,Array.prototype.slice.apply(arguments, [0]));//special case which happens if the user refreshes while in the login screen (history state doesn't change because it goes from login to login and the above listener doesn't trigger) + try { + History.pushState({'state': name, 'params': Array.prototype.slice.apply(arguments, [1])}, null, '?s=' + name); + } + catch (e) { + codeq.log.error('init: History.pushState() failed for new state ' + name+'. Error:'+e); + } + }, + 'destroy': function () { + if (currState !== null) currState.exit(); + currState = null; + History.Adapter.unbind(window, 'statechange', stateChangeFun); + }, + 'register': function (name, state) { + if (name in def) codeq.log.error('The state ' + name + ' is already registered, overriding'); + def[name] = state; + }, + 'actualTransition': function (name) { + var newState = def[name];//if the newState is not the same as the old or if it doesn't exist at all is already checked at this point + if (currState) currState.exit(); + currState = newState; + currState.enter.apply(currState, Array.prototype.slice.apply(arguments, [1])); + } + } + }; + codeq.globalStateMachine = makeGlobalStateMachine({}); + + + //setup all the buttons in the banner + $('#navigation-login').on('click', function(e){ + codeq.globalStateMachine.transition('login'); + e.preventDefault();//prevent this since we'll trigger a page reload otherwise + }); + $('#navigation-language').on('click', function(e){ + codeq.globalStateMachine.transition('language'); + e.preventDefault(); + }); + $('#navigation-problem').on('click', function(e){ + codeq.globalStateMachine.transition('problem'); + e.preventDefault(); + }); + $('#navigation-python').on('click', function(e){ + codeq.globalStateMachine.transition('python'); + e.preventDefault(); + }); + $('#navigation-prolog').on('click', function(e){ + codeq.globalStateMachine.transition('prolog'); + e.preventDefault(); + }); +})();
\ No newline at end of file |