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();
});
})();
|