summaryrefslogtreecommitdiff
path: root/js/codeq/navigation.js
blob: 1a7799f00560f290119e067a3a154704b41b92b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
 * 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, 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-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();
    });
})();