123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582 |
- /*
- This is the core logic for the main page.
- It implements most page transitions by showing and hiding DIV elements
- in the page with javascript+jquery
- */
- /* Convert a JSON string to an object, or null if unparseable */
- function j2o(json) { try { return JSON.parse(json); } catch(e) { return null; } }
- /* Convert an object to a JSON string (just easier to type than "JSON.stringify" */
- function o2j(obj) { return JSON.stringify(obj); }
- var user = {};
- var router = {
- routes: {},
- add: function(name, useAjax, cb) {
- if (typeof useAjax === 'function') {
- cb = useAjax;
- useAjax = true;
- }
- this.routes[name] = {
- fn: cb,
- useAjax: useAjax
- }
- },
- run: function(name, path) {
- $('.nav').removeClass('active');
- checkUser(function() {
- if (router.routes[name].useAjax) {
- $.get(path, {cache: false}, function(data) {
- if (data.status === 'not_found' || (typeof data === 'string')) {
- return router.run('404');
- }
- router.routes[name].fn(data, render);
- });
- } else {
- router.routes[name].fn(render);
- }
- });
- }
- }
- function render(pageId, response) {
- if (user.name) {
- $('.username').text("Hi, "+user.name+"!");
- $("#login_status").show();
- $('#login_link').text('Logout').attr('href', '/logout');
- $('#register_link').hide();
- $('#profile_link').show();
- } else {
- $('.username').text('Guest');
- $("#login_status").hide();
- $('#login_link').text('Login').attr('href', '/login');
- $('#register_link').show();
- $('#profile_link').hide();
- }
- if (response) {
- if (response instanceof Array) {
- $.each(response, function() {
- ProtoDiv.reset("PROTO_" + this.id)
- ProtoDiv.replicate("PROTO_" + this.id, this.data)
- })
- } else {
- ProtoDiv.reset("PROTO_" + response.id)
- ProtoDiv.replicate("PROTO_" + response.id, response.data)
- }
- }
- $("#pg_" + pageId).fadeIn(100);
- }
- function message(type, msg) {
- ProtoDiv.reset("PROTO_message");
- ProtoDiv.replicate("PROTO_message", {type: type, msg: msg})
- $("#messages").fadeIn(100);
- }
- function checkUser(cb) {
- $.get('/checkuser', function(data) {
- if (data.user) {
- user = data.user;
- } else {
- user = {};
- }
- if (cb) {
- cb();
- }
- })
- }
- router.add('404', false, function() {
- $("#pg_notfound").fadeIn(100);
- window.scroll(0, 0)
- });
- router.add('home', false, function(cb) {
- $('#learnsomething').unbind();
- $('.nav').removeClass('active');
- cb("home");
- $('#signup').click(function(e) {
- goPage('/register');
- });
- $('#learnsomething').click(function(e) {
- $.get('/learn/random', function(data) {
- if (data.status === 'ok') {
- goPage(data.data);
- }
- })
- });
- if ($('#vimeo-screencast').length === 0) {
- $('.video-wrapper').html('<iframe id="vimeo-screencast" src="http://player.vimeo.com/video/30647271?title=0&byline=0&portrait=0&color=367da9" width="460" height="259" frameborder="0" webkitAllowFullScreen allowFullScreen></iframe>');
- }
- });
- // go to the page that lists the schools
- router.add('schools', function(data, cb) {
- $('#school_link').addClass('active');
- var response = {
- id: 'school',
- data: data.schools
- }
- cb("schools", response);
- });
- // go to the page that lists the courses for a specific school
- router.add('school', function(data, cb) {
- $('#school_link').addClass('active');
- $('.sub_menu').hide();
- //$('#new_course').unbind();
- $('#form_course').hide().unbind();
- var response = {
- id: 'course',
- data: data.school.courses
- }
- $("#school_name").html(data.school.name);
- if (data.school.authorized) {
- $('.sub_menu').show();
- var form = $('#form_course');
- form.toggle();
- form.submit(function(e) {
- e.preventDefault();
- $.post(window.location.pathname, form.serialize(), function(data) {
- if (data.status === 'error') {
- message('error', data.message);
- } else if (data.status === 'ok') {
- form.hide();
- goPage(window.location.pathname);
- message('info', data.message);
- }
- });
- })
- }
- cb("courses", response)
- });
- // go to the page that lists the lectures for a specific course
- router.add('course', function(data, cb) {
- $('#school_link').addClass('active');
- $('.sub_menu').hide();
- $('#new_lecture').unbind();
- $('#form_lecture').hide().unbind();;
- var response = [];
- if (data.course) {
- response.push({
- id: 'lectures_head',
- data: data.course
- })
- }
- if (data.instructor) {
- response.push({
- id: 'lectures_instructor',
- data: data.instructor
- })
- }
- if (data.lectures) {
- response.push({
- id: 'lecture',
- data: data.lectures.map(function(lecture) {
- var date = new Date(lecture.date);
- lecture.date = date.toDateString();
- return lecture;
- })
- })
- }
- cb('lectures', response);
- if (!data.instructor.email) {
- $('.instructor_email').hide();
- } else {
- $('.instructor_email').show();
- }
- if (data.course.authorized) {
- $('.sub_menu').show();
- $('#new_lecture').click(function(e) {
- e.preventDefault();
- var form = $('#form_lecture');
- form.toggle();
- form.submit(function(e) {
- e.preventDefault();
- $.post(window.location.pathname, form.serialize(), function(data) {
- if (data.status === 'error') {
- message('error', data.message);
- } else if (data.status === 'ok') {
- form.hide();
- goPage(window.location.pathname);
- message('info', data.message);
- }
- });
- })
- });
- }
- });
- // go to the page that lists the note taking sessions for a specific lecture
- router.add('lecture', function(data, cb) {
- $('#school_link').addClass('active');
- $('.sub_menu').hide();
- $('#new_note').unbind();
- $('#form_note').hide().unbind();;
- var response = [];
- if (data.course) {
- response.push({
- id: 'notes_head',
- data: data.course
- })
- }
- if (data.instructor) {
- response.push({
- id: 'notes_instructor',
- data: data.instructor
- })
- }
- if (data.notes) {
- response.push({
- id: 'note',
- data: data.notes
- })
- }
-
- cb("notes", response);
- if (!data.instructor.email) {
- $('.instructor_email').hide();
- } else {
- $('.instructor_email').show();
- }
-
- if (data.lecture.authorized) {
- $('.sub_menu').show();
- $('#new_note').click(function(e) {
- e.preventDefault();
- var form = $('#form_note');
- form.toggle();
- form.submit(function(e) {
- e.preventDefault();
- $.post(window.location.pathname, form.serialize(), function(data) {
- if (data.status === 'error') {
- message('error', data.message);
- } else if (data.status === 'ok') {
- form.hide();
- goPage(window.location.pathname);
- message('info', data.message);
- }
- });
- })
- });
- }
- });
- // go to the page that lists the archived subject names
- router.add('archive', function(data, cb) {
- $('#archive_link').addClass('active');
- var response = {
- id: 'archive_subject',
- data: data.subjects
- }
- cb("archive_subjects", response)
- });
- router.add('archivesubject', function(data, cb) {
- $('.nav').removeClass('active');
- $('#archive_link').addClass('active');
- var response = {
- id: 'archive_course',
- data: data.courses
- }
- cb("archive_courses", response)
- });
- router.add('archivecourse', function(data, cb) {
- $('#archive_link').addClass('active');
- var response = {
- id: 'archive_note',
- data: data.notes
- }
- cb("archive_notes", response)
- });
- router.add('archivenote', function(data, cb) {
- $('#archive_link').addClass('active');
- var response = {
- id: 'archive_note_display',
- data: data.note
- }
- cb("archive_note_display", response)
- });
- // go to the account registration page
- router.add('register', false, function(cb) {
- $('#register_link').addClass('active');
- $('#form_register').submit(function(e) {
- e.preventDefault();
- var form = $(this);
- $.post(window.location.pathname, form.serialize(), function(data) {
- if (data.status === 'error') {
- message('error', data.message);
- return false;
- } else if (data.status === 'ok') {
- goPage('/')
- message('info', data.message);
- }
- })
- })
- cb("register");
- });
- router.add('activate', function(data, cb) {
- goPage('/')
- message('info', data.message);
- });
- router.add('profile', false, function(cb) {
- $('#profile_link').addClass('active');
- var form = $('#form_profile');
- $('input[type=password]','#form_profile').val('');
- $('#affiliation').attr('value', user.affil);
- $('#showName').attr('checked', user.showName)
- form.find('.email').text(user.email);
- form.find('input[name=name]').val(user.name);
- form.submit(function(e) {
- e.preventDefault();
- $.post(window.location.pathname, form.serialize(), function(data) {
- if (data.status === 'error') {
- message('error', data.message);
- return false;
- } else if (data.status === 'ok') {
- goPage('/profile');
- message('info', data.message);
- }
- })
- })
- cb("profile");
- });
- router.add('login', false, function(cb) {
- $('input','#form_login').val('');
- $('#form_login').submit(function(e) {
- e.preventDefault();
- var form = $(this);
- $.post(window.location.pathname, form.serialize(), function(data) {
- if (data.status === 'error') {
- message('error', data.message);
- return false;
- } else if (data.status === 'ok') {
- goPage('/')
- message('info', 'Successfully logged in');
- }
- })
- })
- cb("login");
- });
- router.add('logout', function(data, cb) {
- goPage('/')
- message('info', 'Successfully logged out');
- });
- router.add('resetpass', false, function(cb) {
- $('input','#form_resetpass').val('');
- $('#form_resetpass').submit(function(e) {
- e.preventDefault();
- var form = $(this);
- $.post(window.location.pathname, form.serialize(), function(data) {
- if (data.status === 'error') {
- message('error', data.message);
- return false;
- } else if (data.status === 'ok') {
- goPage('/')
- message('info', data.message);
- }
- })
- })
- cb("resetpass");
- });
- router.add('resetpw', false, function(cb) {
- $('input','#form_resetpw').val('');
- $('#form_resetpw').submit(function(e) {
- e.preventDefault();
- var form = $(this);
- $.post(window.location.pathname, form.serialize(), function(data) {
- if (data.status === 'error') {
- message('error', data.message);
- return false;
- } else if (data.status === 'ok') {
- goPage('/')
- message('info', data.message);
- }
- })
- })
- cb("resetpw");
- });
- // go to the press articles page
- router.add('press', false, function(cb) {
- $('#press_link').addClass('active');
- cb("press");
- });
- // go to the "code of conduct" page
- router.add('conduct', false, function(cb) {
- cb("conduct");
- });
- /* Do and show the appropriate thing, based on the pages current URL */
- function showPage(y) {
- $(".page").hide(); //(100); // hide all pseudo pages
- var path = document.location.pathname
- var routes = router.routes;
- var slugs = path.split('/');
- slugs.shift();
- mainSlug = slugs[0].toLowerCase() || 'home';
- if (mainSlug === 'archive') {
- if (slugs[1]) {
- mainSlug = mainSlug + slugs[1];
- }
- }
- if (routes[mainSlug]) {
- router.run(mainSlug, path)
- } else {
- router.run('404')
- }
- }
- /* Simulates a page load.
- 'path' is something like "/schools", etc.
- A page fetch doesn't really happen.
- Based on what path looks like, an appropriate DIV is shown, and action taken
- */
- var topQueue = [0]
- function goPage(path) {
- if (history.pushState !== undefined) {
- topQueue.push(window.pageYOffset)
- history.pushState({}, path, path);
- showPage(0);
- } else {
- document.location = path;
- }
- }
- /* Simulates a "back" browser navigation. */
- var popped = false;
- function goBack(event) {
- popped = true;
- console.timeEnd('pop')
- showPage( topQueue.pop() );
- }
- console.time('pop')
- console.time('no-pop')
- window.onpopstate = goBack
- $(document).ready(function() {
- // This code executes after the page has been fully loaded
- $('body').on('click', 'a[href^=/]', function(e) {
- var path = e.target.pathname || '/';
- var checkNote = path.match(/\/([a-zA-Z]+)/);
- if (checkNote && checkNote[1] == 'note') {
- return true;
- } else if (!history.pushState) {
- return true;
- } else {
- goPage(path)
- return false;
- }
- })
- // xxx older FF browsers don't fire a page load/reload - deal with it somehow.
- setTimeout(function() {
- console.timeEnd('no-pop')
- if (!popped) {
- showPage( 0 ); // needed for some older browsers, redundant for chrome
- }
- }, 200)
- })
|