From 07629ef45d976714ac72943f47fdc0555c466d67 Mon Sep 17 00:00:00 2001 From: Prem Sichanugrist Date: Thu, 26 Apr 2012 17:39:57 -0400 Subject: [PATCH] Rewrite Courseware navigation --- djangoapps/courseware/views.py | 13 ++- static/js/application.js | 47 ++++++++++- templates/accordion_init.js | 19 ----- templates/coffee/files.json | 4 +- templates/coffee/fixtures/accordion.html | 6 ++ templates/coffee/spec/courseware_spec.coffee | 66 +++++++++++++++ templates/coffee/spec/courseware_spec.js | 85 ++++++++++++++++++++ templates/coffee/src/courseware.coffee | 21 +++++ templates/coffee/src/main.coffee | 1 + 9 files changed, 234 insertions(+), 28 deletions(-) delete mode 100644 templates/accordion_init.js create mode 100644 templates/coffee/fixtures/accordion.html create mode 100644 templates/coffee/spec/courseware_spec.coffee create mode 100644 templates/coffee/spec/courseware_spec.js create mode 100644 templates/coffee/src/courseware.coffee diff --git a/djangoapps/courseware/views.py b/djangoapps/courseware/views.py index f7d1ba9293..cca9674c42 100644 --- a/djangoapps/courseware/views.py +++ b/djangoapps/courseware/views.py @@ -84,7 +84,7 @@ def render_accordion(request,course,chapter,section): parameter. Returns (initialization_javascript, content)''' if not course: course = "6.002 Spring 2012" - + toc=content_parser.toc_from_xml(content_parser.course_file(request.user), chapter, section) active_chapter=1 for i in range(len(toc)): @@ -96,8 +96,7 @@ def render_accordion(request,course,chapter,section): ['format_url_params',content_parser.format_url_params], ['csrf',csrf(request)['csrf_token']]] + \ template_imports.items()) - return {'init_js':render_to_string('accordion_init.js',context), - 'content':render_to_string('accordion.html',context)} + return render_to_string('accordion.html',context) @cache_control(no_cache=True, no_store=True, must_revalidate=True) def render_section(request, section): @@ -124,8 +123,8 @@ def render_section(request, section): if 'init_js' not in module: module['init_js']='' - context={'init':accordion['init_js']+module['init_js'], - 'accordion':accordion['content'], + context={'init':module['init_js'], + 'accordion':accordion, 'content':module['content'], 'csrf':csrf(request)['csrf_token']} @@ -179,8 +178,8 @@ def index(request, course="6.002 Spring 2012", chapter="Using the System", secti if 'init_js' not in module: module['init_js']='' - context={'init':accordion['init_js']+module['init_js'], - 'accordion':accordion['content'], + context={'init':module['init_js'], + 'accordion':accordion, 'content':module['content'], 'csrf':csrf(request)['csrf_token']} diff --git a/static/js/application.js b/static/js/application.js index 1591b6fc44..6a2e883917 100644 --- a/static/js/application.js +++ b/static/js/application.js @@ -39,6 +39,50 @@ })(); + window.Courseware = (function() { + + function Courseware() {} + + Courseware.bind = function() { + return this.Navigation.bind(); + }; + + Courseware.Navigation = (function() { + + function Navigation() {} + + Navigation.bind = function() { + var navigation; + if ($('#accordion').length) { + navigation = new Navigation; + $('#accordion').bind('accordionchange', navigation.log).accordion({ + active: $('#accordion ul:has(li.active)').index('#accordion ul'), + header: 'h3', + autoHeight: false + }); + return $('#open_close_accordion a').click(navigation.toggle); + } + }; + + Navigation.prototype.log = function(event, ui) { + return log_event('accordion', { + newheader: ui.newHeader.text(), + oldheader: ui.oldHeader.text() + }); + }; + + Navigation.prototype.toggle = function() { + return $('.course-wrapper').toggleClass('closed'); + }; + + return Navigation; + + })(); + + return Courseware; + + }).call(this); + window.FeedbackForm = (function() { function FeedbackForm() {} @@ -67,8 +111,9 @@ 'X-CSRFToken': $.cookie('csrftoken') } }); - FeedbackForm.bind(); Calculator.bind(); + Courseware.bind(); + FeedbackForm.bind(); return $("a[rel*=leanModal]").leanModal(); }); diff --git a/templates/accordion_init.js b/templates/accordion_init.js deleted file mode 100644 index 7c4ca2603c..0000000000 --- a/templates/accordion_init.js +++ /dev/null @@ -1,19 +0,0 @@ -$("#accordion").accordion({ - active: ${ active_chapter }, - header: 'h3', - autoHeight: false, -}); - -$("#open_close_accordion a").click(function(){ - if ($(".course-wrapper").hasClass("closed")){ - $(".course-wrapper").removeClass("closed"); - } else { - $(".course-wrapper").addClass("closed"); - } -}); - -$('.ui-accordion').bind('accordionchange', function(event, ui) { - var event_data = {'newheader':ui.newHeader.text(), - 'oldheader':ui.oldHeader.text()}; - log_event('accordion', event_data); -}); diff --git a/templates/coffee/files.json b/templates/coffee/files.json index 44494e8040..bfae4dfe87 100644 --- a/templates/coffee/files.json +++ b/templates/coffee/files.json @@ -1,6 +1,8 @@ { "js_files": [ - "/static/js/jquery-1.6.2.min.js" + "/static/js/jquery-1.6.2.min.js", + "/static/js/jquery-ui-1.8.16.custom.min.js", + "/static/js/jquery.leanModal.js" ], "static_files": [ "js/application.js" diff --git a/templates/coffee/fixtures/accordion.html b/templates/coffee/fixtures/accordion.html new file mode 100644 index 0000000000..148c245c8f --- /dev/null +++ b/templates/coffee/fixtures/accordion.html @@ -0,0 +1,6 @@ +
+
+ close +
+
+
diff --git a/templates/coffee/spec/courseware_spec.coffee b/templates/coffee/spec/courseware_spec.coffee new file mode 100644 index 0000000000..5a5cabac0e --- /dev/null +++ b/templates/coffee/spec/courseware_spec.coffee @@ -0,0 +1,66 @@ +describe 'Courseware', -> + describe 'bind', -> + it 'bind the navigation', -> + spyOn Courseware.Navigation, 'bind' + Courseware.bind() + expect(Courseware.Navigation.bind).toHaveBeenCalled() + + describe 'Navigation', -> + beforeEach -> + loadFixtures 'accordion.html' + @navigation = new Courseware.Navigation + + describe 'bind', -> + describe 'when the #accordion exists', -> + it 'activate the accordion with correct active section', -> + spyOn $.fn, 'accordion' + $('#accordion').append('') + Courseware.Navigation.bind() + expect($('#accordion').accordion).toHaveBeenCalledWith + active: 1 + header: 'h3' + autoHeight: false + + it 'binds the accordionchange event', -> + Courseware.Navigation.bind() + expect($('#accordion')).toHandleWith 'accordionchange', @navigation.log + + it 'bind the navigation toggle', -> + Courseware.Navigation.bind() + expect($('#open_close_accordion a')).toHandleWith 'click', @navigation.toggle + + describe 'when the #accordion does not exists', -> + beforeEach -> + $('#accordion').remove() + + it 'does not activate the accordion', -> + spyOn $.fn, 'accordion' + Courseware.Navigation.bind() + expect($('#accordion').accordion).wasNotCalled() + + describe 'toggle', -> + it 'toggle closed class on the wrapper', -> + $('.course-wrapper').removeClass('closed') + + @navigation.toggle() + expect($('.course-wrapper')).toHaveClass('closed') + + @navigation.toggle() + expect($('.course-wrapper')).not.toHaveClass('closed') + + describe 'log', -> + beforeEach -> + window.log_event = -> + spyOn window, 'log_event' + + it 'submit event log', -> + @navigation.log {}, { + newHeader: + text: -> "new" + oldHeader: + text: -> "old" + } + + expect(window.log_event).toHaveBeenCalledWith 'accordion', + newheader: 'new' + oldheader: 'old' diff --git a/templates/coffee/spec/courseware_spec.js b/templates/coffee/spec/courseware_spec.js new file mode 100644 index 0000000000..195ea7b73b --- /dev/null +++ b/templates/coffee/spec/courseware_spec.js @@ -0,0 +1,85 @@ +// Generated by CoffeeScript 1.3.2-pre +(function() { + + describe('Courseware', function() { + describe('bind', function() { + return it('bind the navigation', function() { + spyOn(Courseware.Navigation, 'bind'); + Courseware.bind(); + return expect(Courseware.Navigation.bind).toHaveBeenCalled(); + }); + }); + return describe('Navigation', function() { + beforeEach(function() { + loadFixtures('accordion.html'); + return this.navigation = new Courseware.Navigation; + }); + describe('bind', function() { + describe('when the #accordion exists', function() { + it('activate the accordion with correct active section', function() { + spyOn($.fn, 'accordion'); + $('#accordion').append(''); + Courseware.Navigation.bind(); + return expect($('#accordion').accordion).toHaveBeenCalledWith({ + active: 1, + header: 'h3', + autoHeight: false + }); + }); + it('binds the accordionchange event', function() { + Courseware.Navigation.bind(); + return expect($('#accordion')).toHandleWith('accordionchange', this.navigation.log); + }); + return it('bind the navigation toggle', function() { + Courseware.Navigation.bind(); + return expect($('#open_close_accordion a')).toHandleWith('click', this.navigation.toggle); + }); + }); + return describe('when the #accordion does not exists', function() { + beforeEach(function() { + return $('#accordion').remove(); + }); + return it('does not activate the accordion', function() { + spyOn($.fn, 'accordion'); + Courseware.Navigation.bind(); + return expect($('#accordion').accordion).wasNotCalled(); + }); + }); + }); + describe('toggle', function() { + return it('toggle closed class on the wrapper', function() { + $('.course-wrapper').removeClass('closed'); + this.navigation.toggle(); + expect($('.course-wrapper')).toHaveClass('closed'); + this.navigation.toggle(); + return expect($('.course-wrapper')).not.toHaveClass('closed'); + }); + }); + return describe('log', function() { + beforeEach(function() { + window.log_event = function() {}; + return spyOn(window, 'log_event'); + }); + return it('submit event log', function() { + this.navigation.log({}, { + newHeader: { + text: function() { + return "new"; + } + }, + oldHeader: { + text: function() { + return "old"; + } + } + }); + return expect(window.log_event).toHaveBeenCalledWith('accordion', { + newheader: 'new', + oldheader: 'old' + }); + }); + }); + }); + }); + +}).call(this); diff --git a/templates/coffee/src/courseware.coffee b/templates/coffee/src/courseware.coffee new file mode 100644 index 0000000000..7772c1e533 --- /dev/null +++ b/templates/coffee/src/courseware.coffee @@ -0,0 +1,21 @@ +class window.Courseware + @bind: -> + @Navigation.bind() + + class @Navigation + @bind: -> + if $('#accordion').length + navigation = new Navigation + $('#accordion').bind('accordionchange', navigation.log).accordion + active: $('#accordion ul:has(li.active)').index('#accordion ul') + header: 'h3' + autoHeight: false + $('#open_close_accordion a').click navigation.toggle + + log: (event, ui) -> + log_event 'accordion', + newheader: ui.newHeader.text() + oldheader: ui.oldHeader.text() + + toggle: -> + $('.course-wrapper').toggleClass('closed') diff --git a/templates/coffee/src/main.coffee b/templates/coffee/src/main.coffee index dc8c4a0622..8a9a892f94 100644 --- a/templates/coffee/src/main.coffee +++ b/templates/coffee/src/main.coffee @@ -3,5 +3,6 @@ $ -> headers : { 'X-CSRFToken': $.cookie 'csrftoken' } Calculator.bind() + Courseware.bind() FeedbackForm.bind() $("a[rel*=leanModal]").leanModal()