index.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. // TODO - Add initial page loading and handlers
  2. (function($,History){
  3. var State = History.getState(),
  4. Old = {},
  5. Key = null,
  6. flags = [],
  7. flag = window.flag = function(name,value){
  8. if(exists(value)){
  9. flags[name] = value;
  10. }else{
  11. return exists(flags[name])?flags[name]:false;
  12. }
  13. },
  14. settings = {},
  15. exists = function(v){
  16. return typeof v != 'undefined';
  17. },
  18. get = window.get = function(s){
  19. return settings[s];
  20. },
  21. set = window.set = function(s,v){
  22. settings[s] = v;
  23. return v;
  24. },
  25. setKey = window.setKey = function(key){
  26. if(key !== null){
  27. console.log('Key change to '+key);
  28. Key = key;
  29. var d = new Date();
  30. d.setTime(d.getTime()+get('timeout'));
  31. $.cookie('key',key,{
  32. expires: d
  33. });
  34. }else{
  35. console.log('Key deleted');
  36. Key = null;
  37. $.removeCookie('key');
  38. }
  39. },
  40. getKey = window.getKey = function(){
  41. return Key;
  42. },
  43. apiCall = window.apiCall = function(data,callback){
  44. console.log('apiCall('+data.type+'-'+data.id+')');
  45. $('#loading').show();
  46. data.get = 'api';
  47. data.timestamp = +new Date;
  48. $.get(location.href,data,function(d){
  49. if(exists(d['error'])){
  50. error(d);
  51. }else{
  52. if(location.href.substr(location.href.lastIndexOf('/')+1) != d.state.url){
  53. console.log('Forced redirection to '+d.state.url);
  54. History.replaceState(d.state.data,d.state.title,d.state.url);
  55. }
  56. }
  57. if(exists(callback)){
  58. callback(d);
  59. }
  60. },'json');
  61. },
  62. loadState = window.loadState = function(href,callback){
  63. console.log('loadState('+href+')');
  64. $('#loading').show();
  65. var data = {
  66. get:'state',
  67. timestamp: +new Date
  68. };
  69. $.get(href,data,function(d){
  70. if(exists(d['error'])){
  71. error(d);
  72. }else{
  73. History.pushState(d.state.data,d.state.title,href);
  74. getNewState();
  75. }
  76. if(exists(callback)){
  77. callback(d);
  78. }
  79. },'json');
  80. },
  81. apiState = window.apiState = function(href,callback){
  82. console.log('apiState('+href+')');
  83. $('#loading').show();
  84. var data = {
  85. get:'state',
  86. timestamp: +new Date
  87. };
  88. $.get(href,data,function(d){
  89. if(exists(d['error'])){
  90. error(d);
  91. }else{
  92. History.replaceState(d.state.data,d.state.title,href);
  93. getNewState();
  94. }
  95. if(exists(callback)){
  96. callback(d);
  97. }
  98. },'json');
  99. },
  100. error = function(e){
  101. e = '['+State.url+']'+e.error;
  102. console.error(e+"\n"+(exists(e.state)?JSON.stringify(e.state):''));
  103. alert(e);
  104. },
  105. getNewState = function(){
  106. State = History.getState();
  107. console.log("State change. "+JSON.stringify(State.data));
  108. if (!window.location.origin) {
  109. window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
  110. }
  111. },
  112. equal = function(o1,o2){
  113. for(var i in o1){
  114. if(!exists(o2[i])||o2[i]!=o1[i]){
  115. return false;
  116. }
  117. }
  118. for(i in o2){
  119. if(!exists(o1[i])||o2[i]!=o1[i]){
  120. return false;
  121. }
  122. }
  123. return true;
  124. },
  125. render = window.render = {
  126. topbar: function(t,c){
  127. $('#topbar').html(Handlebars.compile(t)(c));
  128. render.links('#topbar');
  129. },
  130. content: function(t,c){
  131. $('#content').html(
  132. Handlebars.compile(t)(c)
  133. );
  134. render.links('#content');
  135. $(window).resize();
  136. },
  137. links: function(selector){
  138. $(selector).find('a').each(function(){
  139. var href = this.href;
  140. if(href.indexOf('#')!=-1&&(href.indexOf(location.origin)!=-1||href.indexOf('#')==0)){
  141. href = href.substr(href.indexOf('#')+1);
  142. $(this).click(function(e){
  143. try{
  144. if(($(this).hasClass('topbar-home') || $(this).hasClass('topbar-back'))&&$(window).width()<767){
  145. $('#topbar').children('div.topbar-right,div.topbar-left').toggle();
  146. $('#topbar').resize();
  147. }else if($(this).hasClass('topbar-history')){
  148. History.back();
  149. }else{
  150. loadState(href);
  151. }
  152. }catch(error){
  153. console.error(error);
  154. }
  155. e.preventDefault();
  156. return false;
  157. });
  158. }
  159. });
  160. }
  161. };
  162. if(exists($.cookie('key'))){
  163. setKey($.cookie('key'));
  164. }else{
  165. setKey(null);
  166. }
  167. $(document).ready(function(){
  168. if(!exists($.support.touch)){
  169. $.support.touch = 'ontouchstart' in window || 'onmsgesturechange' in window;
  170. }
  171. $(window).on('statechange',function(){
  172. getNewState();
  173. if(!equal(State.data,Old)){
  174. document.title = State.title;
  175. switch(State.data.type){
  176. case 'page':case 'user':
  177. apiCall(State.data,function(d){
  178. if(exists(d.context)){
  179. if(!exists(d.context.key)&&Key!==null){
  180. console.log('Context detected logout');
  181. setKey(null);
  182. }
  183. render.topbar(d.topbar.template,d.topbar.context);
  184. render.content(d.template,d.context);
  185. $('#loading').hide();
  186. }else{
  187. console.error('No context given');
  188. History.back();
  189. }
  190. });
  191. break;
  192. case 'action':break;
  193. default:
  194. error({
  195. url: State.url,
  196. error: "Something went wrong!"
  197. });
  198. }
  199. Old = State.data;
  200. }else{
  201. console.log(State.data,Old);
  202. console.warn('Stopped double load of '+Old.type+'-'+Old.id);
  203. $('#loading').hide();
  204. }
  205. });
  206. if($.isEmptyObject(State.data)){
  207. History.replaceState({
  208. type: 'page',
  209. id: 'index'
  210. },'Bugs','page-index');
  211. console.log('Forcing default state.');
  212. }else{
  213. flag('load',true);
  214. }
  215. var data = {
  216. get: 'settings',
  217. timestamp: +new Date
  218. };
  219. $.get(location.href,data,function(d){
  220. settings = d;
  221. apiState(location.href,function(){
  222. if(flag('load')){
  223. State.data = {
  224. type: '',
  225. data: ''
  226. };
  227. }
  228. flag('load',false);
  229. });
  230. },'json');
  231. $('#content').niceScroll({
  232. cursorwidth: 10,
  233. nativeparentscrolling: false,
  234. preservenativescrolling: false
  235. });
  236. document.addEventListener('touchmove',function(e){
  237. e.preventDefault();
  238. });
  239. });
  240. $(window).resize(function(){
  241. if($(window).width()>767){
  242. $('#topbar div.topbar-right, #topbar div.topbar-left').css({
  243. 'display': ''
  244. });
  245. }else{
  246. $('#content').height($('body').height()-$('#topbar').height());
  247. $('#content').getNiceScroll().resize();
  248. }
  249. }).resize();
  250. $('#topbar').resize(function(){
  251. $(window).resize();
  252. });
  253. shortcut.add('f12',function(){
  254. if(!flag('firebug-lite')){
  255. (function(F,i,r,e,b,u,g,L,I,T,E){
  256. if(F.getElementById(b))
  257. return;
  258. E=F[i+'NS']&&F.documentElement.namespaceURI;
  259. E=E?F[i+'NS'](E,'script'):F[i]('script');
  260. E[r]('id',b);
  261. E[r]('src',I+g+T);
  262. E[r](b,u);
  263. (F[e]('head')[0]||F[e]('body')[0]).appendChild(E);
  264. E=new Image;
  265. E[r]('src',I+L);
  266. })(document,'createElement','setAttribute','getElementsByTagName','FirebugLite','4','firebug-lite.js','releases/lite/latest/skin/xp/sprite.png','https://getfirebug.com/','#startOpened');
  267. flag('firebug-lite',true);
  268. }
  269. });
  270. $.fn.serializeObject = function(){
  271. var o = {},
  272. a = this.serializeArray();
  273. $.each(a,function(){
  274. if(o[this.name] !== undefined){
  275. if(!o[this.name].push){
  276. o[this.name] = [o[this.name]];
  277. }
  278. o[this.name].push(this.value || '');
  279. }else{
  280. o[this.name] = this.value || '';
  281. }
  282. });
  283. return o;
  284. };
  285. $.ajaxSetup({
  286. async: false
  287. });
  288. })(jQuery,History);