4 This is the core logic for the main page.
5 It implements most page transitions by showing and hiding DIV elements
6 in the page with javascript+jquery
11 /* Convert a JSON string to an object, or null if unparseable */
12 function j2o(json) { try { return JSON.parse(json); } catch(e) { return null; } }
14 /* Convert an object to a JSON string (just easier to type than "JSON.stringify" */
15 function o2j(obj) { return JSON.stringify(obj); }
21 add: function(name, useAjax, cb) {
22 if (typeof useAjax === 'function') {
31 run: function(name, path) {
32 checkUser(function() {
33 if (router.routes[name].useAjax) {
34 $.get(path, {cache: false}, function(data) {
35 if (data.status === 'not_found' || (typeof data === 'string')) {
36 return router.run('404');
38 router.routes[name].fn(data, render);
41 router.routes[name].fn(render);
47 function render(pageId, response) {
49 $('.username').text(user.name);
50 $("#login_status").show();
51 $('#login_link').text('Logout').attr('href', '/logout');
52 $('#register_link').hide();
53 $('#profile_link').show();
55 $('.username').text('');
56 $("#login_status").hide();
57 $('#login_link').text('Login').attr('href', '/login');
58 $('#register_link').show();
59 $('#profile_link').hide();
62 if (response instanceof Array) {
63 $.each(response, function() {
64 ProtoDiv.reset("PROTO_" + this.id)
65 ProtoDiv.replicate("PROTO_" + this.id, this.data)
68 ProtoDiv.reset("PROTO_" + response.id)
69 ProtoDiv.replicate("PROTO_" + response.id, response.data)
72 $("#pg_" + pageId).fadeIn(100);
75 function message(type, msg) {
76 ProtoDiv.reset("PROTO_message");
77 ProtoDiv.replicate("PROTO_message", {type: type, msg: msg})
78 $("#messages").fadeIn(100);
81 function checkUser(cb) {
82 $.get('/checkuser', function(data) {
95 router.add('404', false, function() {
96 $("#pg_notfound").fadeIn(100);
100 router.add('home', false, function(cb) {
101 $('#learnsomething').unbind();
103 $('#learnsomething').click(function(e) {
104 $.get('/learn/random', function(data) {
105 if (data.status === 'ok') {
110 if ($('#vimeo-screencast').length === 0) {
111 $('#screencast').html('<iframe id="vimeo-screencast" src="http://player.vimeo.com/video/30647271?title=0&byline=0&portrait=0" width="350" height="250" frameborder="0" webkitallowfullscreen="webkitAllowFullScreen" allowfullscreen="allowFullScreen"></iframe>');
117 // go to the page that lists the schools
118 router.add('schools', function(data, cb) {
125 cb("schools", response);
130 // go to the page that lists the courses for a specific school
131 router.add('school', function(data, cb) {
132 $('.sub_menu').hide();
133 $('#new_course').unbind();
134 $('#form_course').hide().unbind();
137 data: data.school.courses
140 $("#school_name").html(data.school.name);
142 if (data.school.authorized) {
143 $('.sub_menu').show();
144 $('#new_course').click(function(e) {
147 var form = $('#form_course');
151 form.submit(function(e) {
154 $.post(window.location.pathname, form.serialize(), function(data) {
155 if (data.status === 'error') {
156 message('error', data.message);
157 } else if (data.status === 'ok') {
159 goPage(window.location.pathname);
160 message('info', data.message);
166 cb("courses", response)
172 // go to the page that lists the lectures for a specific course
173 router.add('course', function(data, cb) {
174 $('.sub_menu').hide();
175 $('#new_lecture').unbind();
176 $('#form_lecture').hide().unbind();;
187 if (data.instructor) {
189 id: 'lectures_instructor',
190 data: data.instructor
197 data: data.lectures.map(function(lecture) {
198 var date = new Date(lecture.date);
199 lecture.date = date.toDateString();
204 cb('lectures', response);
206 if (!data.instructor.email) {
207 $('.instructor_email').hide();
209 $('.instructor_email').show();
212 if (data.course.authorized) {
213 $('.sub_menu').show();
214 $('#new_lecture').click(function(e) {
217 var form = $('#form_lecture');
221 form.submit(function(e) {
224 $.post(window.location.pathname, form.serialize(), function(data) {
225 if (data.status === 'error') {
226 message('error', data.message);
227 } else if (data.status === 'ok') {
229 goPage(window.location.pathname);
230 message('info', data.message);
241 // go to the page that lists the note taking sessions for a specific lecture
242 router.add('lecture', function(data, cb) {
243 $('.sub_menu').hide();
244 $('#new_note').unbind();
245 $('#form_note').hide().unbind();;
256 if (data.instructor) {
258 id: 'notes_instructor',
259 data: data.instructor
270 cb("notes", response);
272 if (!data.instructor.email) {
273 $('.instructor_email').hide();
275 $('.instructor_email').show();
278 if (data.lecture.authorized) {
279 $('.sub_menu').show();
280 $('#new_note').click(function(e) {
283 var form = $('#form_note');
287 form.submit(function(e) {
290 $.post(window.location.pathname, form.serialize(), function(data) {
291 if (data.status === 'error') {
292 message('error', data.message);
293 } else if (data.status === 'ok') {
295 goPage(window.location.pathname);
296 message('info', data.message);
305 // go to the page that lists the archived subject names
306 router.add('archive', function(data, cb) {
309 id: 'archive_subject',
313 cb("archive_subjects", response)
318 router.add('archivesubject', function(data, cb) {
321 id: 'archive_course',
325 cb("archive_courses", response)
330 router.add('archivecourse', function(data, cb) {
337 cb("archive_notes", response)
342 router.add('archivenote', function(data, cb) {
345 id: 'archive_note_display',
349 cb("archive_note_display", response)
354 // go to the account registration page
355 router.add('register', false, function(cb) {
356 $('#form_register').submit(function(e) {
361 $.post(window.location.pathname, form.serialize(), function(data) {
362 if (data.status === 'error') {
363 message('error', data.message);
365 } else if (data.status === 'ok') {
367 message('info', data.message);
374 router.add('activate', function(data, cb) {
376 message('info', data.message);
379 router.add('profile', false, function(cb) {
380 var form = $('#form_profile');
381 $('input[type=password]','#form_profile').val('');
382 $('#affiliation').attr('value', user.affil);
383 $('#showName').attr('checked', user.showName)
384 form.find('.email').text(user.email);
385 form.find('input[name=name]').val(user.name);
386 form.submit(function(e) {
389 $.post(window.location.pathname, form.serialize(), function(data) {
390 if (data.status === 'error') {
391 message('error', data.message);
393 } else if (data.status === 'ok') {
395 message('info', data.message);
402 router.add('login', false, function(cb) {
403 $('input','#form_login').val('');
404 $('#form_login').submit(function(e) {
409 $.post(window.location.pathname, form.serialize(), function(data) {
410 if (data.status === 'error') {
411 message('error', data.message);
413 } else if (data.status === 'ok') {
415 message('info', 'Successfully logged in');
422 router.add('logout', function(data, cb) {
424 message('info', 'Successfully logged out');
427 router.add('resetpass', false, function(cb) {
428 $('input','#form_resetpass').val('');
429 $('#form_resetpass').submit(function(e) {
434 $.post(window.location.pathname, form.serialize(), function(data) {
435 if (data.status === 'error') {
436 message('error', data.message);
438 } else if (data.status === 'ok') {
440 message('info', data.message);
447 router.add('resetpw', false, function(cb) {
448 $('input','#form_resetpw').val('');
449 $('#form_resetpw').submit(function(e) {
454 $.post(window.location.pathname, form.serialize(), function(data) {
455 if (data.status === 'error') {
456 message('error', data.message);
458 } else if (data.status === 'ok') {
460 message('info', data.message);
467 // go to the press articles page
468 router.add('press', false, function(cb) {
473 // go to the "code of conduct" page
474 router.add('conduct', false, function(cb) {
480 /* Do and show the appropriate thing, based on the pages current URL */
481 function showPage(y) {
483 $(".page").hide(); //(100); // hide all pseudo pages
485 var path = document.location.pathname
486 var routes = router.routes;
488 var slugs = path.split('/');
492 mainSlug = slugs[0].toLowerCase() || 'home';
494 if (mainSlug === 'archive') {
496 mainSlug = mainSlug + slugs[1];
500 if (routes[mainSlug]) {
501 router.run(mainSlug, path)
511 /* Simulates a page load.
512 'path' is something like "/schools", etc.
513 A page fetch doesn't really happen.
514 Based on what path looks like, an appropriate DIV is shown, and action taken
517 function goPage(path) {
518 if (history.pushState !== undefined) {
519 topQueue.push(window.pageYOffset)
520 history.pushState({}, path, path);
523 document.location = path;
528 /* Simulates a "back" browser navigation. */
530 function goBack(event) {
532 showPage( topQueue.pop() );
536 window.onpopstate = goBack
538 $(document).ready(function() {
540 // This code executes after the page has been fully loaded
542 $('body').on('click', 'a[href^=/]', function(e) {
543 var path = e.target.pathname || '/';
544 var checkNote = path.match(/\/([a-zA-Z]+)/);
545 if (checkNote && checkNote[1] == 'note') {
547 } else if (!history.pushState) {
555 // xxx older FF browsers don't fire a page load/reload - deal with it somehow.
556 setTimeout(function() {
558 showPage( 0 ); // needed for some older browsers, redundant for chrome