From 1136336fc484556e79effa0a9a71194eaaaa9d58 Mon Sep 17 00:00:00 2001 From: Valera Rozuvan Date: Wed, 5 Mar 2014 19:26:55 +0200 Subject: [PATCH] Converting collapsible module to JavaScript. --- .../lib/xmodule/xmodule/annotatable_module.py | 15 ++- common/lib/xmodule/xmodule/capa_module.py | 18 ++- .../xmodule/combined_open_ended_module.py | 13 +- .../lib/xmodule/xmodule/conditional_module.py | 13 +- common/lib/xmodule/xmodule/html_module.py | 6 +- common/lib/xmodule/xmodule/js/spec/.gitignore | 1 + .../xmodule/js/spec/collapsible.coffee | 115 ---------------- .../xmodule/js/spec/collapsible_spec.js | 125 ++++++++++++++++++ common/lib/xmodule/xmodule/js/src/.gitignore | 1 + .../xmodule/xmodule/js/src/collapsible.coffee | 53 -------- .../lib/xmodule/xmodule/js/src/collapsible.js | 110 +++++++++++++++ .../xmodule/xmodule/peer_grading_module.py | 5 +- .../xmodule/xmodule/videoannotation_module.py | 16 ++- 13 files changed, 290 insertions(+), 201 deletions(-) delete mode 100644 common/lib/xmodule/xmodule/js/spec/collapsible.coffee create mode 100644 common/lib/xmodule/xmodule/js/spec/collapsible_spec.js delete mode 100644 common/lib/xmodule/xmodule/js/src/collapsible.coffee create mode 100644 common/lib/xmodule/xmodule/js/src/collapsible.js diff --git a/common/lib/xmodule/xmodule/annotatable_module.py b/common/lib/xmodule/xmodule/annotatable_module.py index fbc175b5b9..ec519a2193 100644 --- a/common/lib/xmodule/xmodule/annotatable_module.py +++ b/common/lib/xmodule/xmodule/annotatable_module.py @@ -40,11 +40,16 @@ class AnnotatableFields(object): class AnnotatableModule(AnnotatableFields, XModule): - js = {'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee'), - resource_string(__name__, 'js/src/collapsible.coffee'), - resource_string(__name__, 'js/src/html/display.coffee'), - resource_string(__name__, 'js/src/annotatable/display.coffee')], - 'js': []} + js = { + 'coffee': [ + resource_string(__name__, 'js/src/javascript_loader.coffee'), + resource_string(__name__, 'js/src/html/display.coffee'), + resource_string(__name__, 'js/src/annotatable/display.coffee'), + ], + 'js': [ + resource_string(__name__, 'js/src/collapsible.js'), + ] + } js_module_name = "Annotatable" css = {'scss': [resource_string(__name__, 'css/annotatable/display.scss')]} icon_class = 'annotatable' diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index a6151011b5..6aa88b673d 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -23,13 +23,17 @@ class CapaModule(CapaMixin, XModule): """ icon_class = 'problem' - js = {'coffee': [resource_string(__name__, 'js/src/capa/display.coffee'), - resource_string(__name__, 'js/src/collapsible.coffee'), - resource_string(__name__, 'js/src/javascript_loader.coffee'), - ], - 'js': [resource_string(__name__, 'js/src/capa/imageinput.js'), - resource_string(__name__, 'js/src/capa/schematic.js') - ]} + js = { + 'coffee': [ + resource_string(__name__, 'js/src/capa/display.coffee'), + resource_string(__name__, 'js/src/javascript_loader.coffee'), + ], + 'js': [ + resource_string(__name__, 'js/src/collapsible.js'), + resource_string(__name__, 'js/src/capa/imageinput.js'), + resource_string(__name__, 'js/src/capa/schematic.js'), + ] + } js_module_name = "Problem" css = {'scss': [resource_string(__name__, 'css/capa/display.scss')]} diff --git a/common/lib/xmodule/xmodule/combined_open_ended_module.py b/common/lib/xmodule/xmodule/combined_open_ended_module.py index 1952423ab2..a807c04bdd 100644 --- a/common/lib/xmodule/xmodule/combined_open_ended_module.py +++ b/common/lib/xmodule/xmodule/combined_open_ended_module.py @@ -395,12 +395,13 @@ class CombinedOpenEndedModule(CombinedOpenEndedFields, XModule): icon_class = 'problem' js = { - 'coffee': - [ - resource_string(__name__, 'js/src/combinedopenended/display.coffee'), - resource_string(__name__, 'js/src/collapsible.coffee'), - resource_string(__name__, 'js/src/javascript_loader.coffee'), - ] + 'coffee': [ + resource_string(__name__, 'js/src/combinedopenended/display.coffee'), + resource_string(__name__, 'js/src/javascript_loader.coffee'), + ], + 'js': [ + resource_string(__name__, 'js/src/collapsible.js'), + ] } js_module_name = "CombinedOpenEnded" diff --git a/common/lib/xmodule/xmodule/conditional_module.py b/common/lib/xmodule/xmodule/conditional_module.py index 67a17aca1b..4c05737d0c 100644 --- a/common/lib/xmodule/xmodule/conditional_module.py +++ b/common/lib/xmodule/xmodule/conditional_module.py @@ -63,10 +63,15 @@ class ConditionalModule(ConditionalFields, XModule): """ - js = {'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee'), - resource_string(__name__, 'js/src/conditional/display.coffee'), - resource_string(__name__, 'js/src/collapsible.coffee'), - ]} + js = { + 'coffee': [ + resource_string(__name__, 'js/src/javascript_loader.coffee'), + resource_string(__name__, 'js/src/conditional/display.coffee'), + ], + 'js': [ + resource_string(__name__, 'js/src/collapsible.js'), + ] + } js_module_name = "Conditional" css = {'scss': [resource_string(__name__, 'css/capa/display.scss')]} diff --git a/common/lib/xmodule/xmodule/html_module.py b/common/lib/xmodule/xmodule/html_module.py index 98183ff537..589358a4eb 100644 --- a/common/lib/xmodule/xmodule/html_module.py +++ b/common/lib/xmodule/xmodule/html_module.py @@ -42,12 +42,12 @@ class HtmlModule(HtmlFields, XModule): js = { 'coffee': [ resource_string(__name__, 'js/src/javascript_loader.coffee'), - resource_string(__name__, 'js/src/collapsible.coffee'), - resource_string(__name__, 'js/src/html/display.coffee') + resource_string(__name__, 'js/src/html/display.coffee'), ], 'js': [ + resource_string(__name__, 'js/src/collapsible.js'), resource_string(__name__, 'js/src/html/imageModal.js'), - resource_string(__name__, 'js/common_static/js/vendor/draggabilly.pkgd.js') + resource_string(__name__, 'js/common_static/js/vendor/draggabilly.pkgd.js'), ] } js_module_name = "HTMLModule" diff --git a/common/lib/xmodule/xmodule/js/spec/.gitignore b/common/lib/xmodule/xmodule/js/spec/.gitignore index 0f9afc716a..951c538ae2 100644 --- a/common/lib/xmodule/xmodule/js/spec/.gitignore +++ b/common/lib/xmodule/xmodule/js/spec/.gitignore @@ -5,3 +5,4 @@ # Tests for Time are written in pure JavaScript. !time_spec.js +!collapsible_spec.js diff --git a/common/lib/xmodule/xmodule/js/spec/collapsible.coffee b/common/lib/xmodule/xmodule/js/spec/collapsible.coffee deleted file mode 100644 index 181d6b46c1..0000000000 --- a/common/lib/xmodule/xmodule/js/spec/collapsible.coffee +++ /dev/null @@ -1,115 +0,0 @@ -describe 'Collapsible', -> - html = custom_labels = html_custom = el = undefined - - initialize = (template) => - setFixtures(template) - el = $('.collapsible') - Collapsible.setCollapsibles(el) - - disableFx = () => - $.fx.off = true - - enableFx = () => - $.fx.off = false - - beforeEach -> - html = ''' -
-
- shortform message -
-
-

longform is visible

-
-
- ''' - html_custom = ''' -
-
- shortform message -
-
-

longform is visible

-
-
- ''' - - describe 'setCollapsibles', -> - - it 'Default container initialized correctly', -> - initialize(html) - - expect(el.find('.shortform')).toContain '.full-top' - expect(el.find('.shortform')).toContain '.full-bottom' - expect(el.find('.longform')).toBeHidden() - expect(el.find('.full')).toHandle('click') - - it 'Custom container initialized correctly', -> - initialize(html_custom) - - expect(el.find('.shortform-custom')).toContain '.full-custom' - expect(el.find('.full-custom')).toHaveText "Show shortform-custom" - expect(el.find('.longform')).toBeHidden() - expect(el.find('.full-custom')).toHandle('click') - - describe 'toggleFull', -> - - beforeEach -> - disableFx() - - afterEach -> - enableFx() - - it 'Default container', -> - initialize(html) - - event = jQuery.Event('click', { - target: el.find('.full').get(0) - }) - - assertChanges = (state='closed') => - anchors = el.find('.full') - - if state is 'closed' - expect(el.find('.longform')).toBeHidden() - expect(el).not.toHaveClass('open') - text = "See full output" - else - expect(el.find('.longform')).toBeVisible() - expect(el).toHaveClass('open') - text = "Hide output" - - $.each anchors, (index, el) => - expect(el).toHaveText text - - Collapsible.toggleFull(event, "See full output", "Hide output") - assertChanges('opened') - Collapsible.toggleFull(event, "See full output", "Hide output") - assertChanges('closed') - - it 'Custom container', -> - initialize(html_custom) - - event = jQuery.Event('click', { - target: el.find('.full-custom').get(0) - }) - - assertChanges = (state='closed') => - anchors = el.find('.full-custom') - - if state is 'closed' - expect(el.find('.longform')).toBeHidden() - expect(el).not.toHaveClass('open') - text = "Show shortform-custom" - else - expect(el.find('.longform')).toBeVisible() - expect(el).toHaveClass('open') - text = "Hide shortform-custom" - - $.each anchors, (index, el) => - expect(el).toHaveText text - - Collapsible.toggleFull(event, "Show shortform-custom", "Hide shortform-custom") - assertChanges('opened') - Collapsible.toggleFull(event, "Show shortform-custom", "Hide shortform-custom") - assertChanges('closed') diff --git a/common/lib/xmodule/xmodule/js/spec/collapsible_spec.js b/common/lib/xmodule/xmodule/js/spec/collapsible_spec.js new file mode 100644 index 0000000000..06a4aae63f --- /dev/null +++ b/common/lib/xmodule/xmodule/js/spec/collapsible_spec.js @@ -0,0 +1,125 @@ +(function (undefined) { + 'use strict'; + + describe('Collapsible', function () { + var el, html, html_custom, + initialize = function (template) { + setFixtures(template); + el = $('.collapsible'); + Collapsible.setCollapsibles(el); + }, + disableFx = function () { + $.fx.off = true; + }, + enableFx = function () { + $.fx.off = false; + }; + + beforeEach(function () { + html = '' + + '
' + + '
shortform message
' + + '
' + + '

longform is visible

' + + '
' + + '
'; + html_custom = '' + + '
' + + '
shortform message
' + + '
' + + '

longform is visible

' + + '
' + + '
'; + }); + + describe('setCollapsibles', function () { + it('Default container initialized correctly', function () { + initialize(html); + + expect(el.find('.shortform')).toContain('.full-top'); + expect(el.find('.shortform')).toContain('.full-bottom'); + expect(el.find('.longform')).toBeHidden(); + expect(el.find('.full')).toHandle('click'); + }); + + it('Custom container initialized correctly', function () { + initialize(html_custom); + + expect(el.find('.shortform-custom')).toContain('.full-custom'); + expect(el.find('.full-custom')).toHaveText('Show shortform-custom'); + expect(el.find('.longform')).toBeHidden(); + expect(el.find('.full-custom')).toHandle('click'); + }); + }); + + describe('toggleFull', function () { + var assertChanges = function (state, anchorsElClass, showText, hideText) { + var anchors, text; + + if (state == null) { + state = 'closed'; + } + + anchors = el.find('.' + anchorsElClass); + + if (state === 'closed') { + expect(el.find('.longform')).toBeHidden(); + expect(el).not.toHaveClass('open'); + text = showText; + } else { + expect(el.find('.longform')).toBeVisible(); + expect(el).toHaveClass('open'); + text = hideText; + } + + $.each(anchors, function (index, el) { + expect(el).toHaveText(text); + }); + }; + + beforeEach(function () { + disableFx(); + }); + + afterEach(function () { + enableFx(); + }); + + it('Default container', function () { + var event; + + initialize(html); + + event = jQuery.Event('click', { + target: el.find('.full').get(0) + }); + + Collapsible.toggleFull(event, 'See full output', 'Hide output'); + assertChanges('opened', 'full', 'See full output', 'Hide output'); + + Collapsible.toggleFull(event, 'See full output', 'Hide output'); + assertChanges('closed', 'full', 'See full output', 'Hide output'); + }); + + it('Custom container', function () { + var event; + + initialize(html_custom); + + event = jQuery.Event('click', { + target: el.find('.full-custom').get(0) + }); + + Collapsible.toggleFull(event, 'Show shortform-custom', 'Hide shortform-custom'); + assertChanges('opened', 'full-custom', 'Show shortform-custom', 'Hide shortform-custom'); + + Collapsible.toggleFull(event, 'Show shortform-custom', 'Hide shortform-custom'); + assertChanges('closed', 'full-custom', 'Show shortform-custom', 'Hide shortform-custom'); + }); + }); + }); +}).call(this); diff --git a/common/lib/xmodule/xmodule/js/src/.gitignore b/common/lib/xmodule/xmodule/js/src/.gitignore index 73a4527726..5a20f017dc 100644 --- a/common/lib/xmodule/xmodule/js/src/.gitignore +++ b/common/lib/xmodule/xmodule/js/src/.gitignore @@ -11,3 +11,4 @@ # Converted to JS from CoffeeScript. !time.js +!collapsible.js diff --git a/common/lib/xmodule/xmodule/js/src/collapsible.coffee b/common/lib/xmodule/xmodule/js/src/collapsible.coffee deleted file mode 100644 index 837231c482..0000000000 --- a/common/lib/xmodule/xmodule/js/src/collapsible.coffee +++ /dev/null @@ -1,53 +0,0 @@ -class @Collapsible - - # Set of library functions that provide a simple way to add collapsible - # functionality to elements. - - # setCollapsibles: - # Scan element's content for generic collapsible containers - @setCollapsibles: (el) => - ### - el: container - ### - linkTop = 'See full output' - linkBottom = 'See full output' - - # standard longform + shortfom pattern - el.find('.longform').hide() - el.find('.shortform').append(linkTop, linkBottom) - - # custom longform + shortform text pattern - short_custom = el.find('.shortform-custom') - # set up each one individually - short_custom.each (index, elt) => - open_text = $(elt).data('open-text') - close_text = $(elt).data('close-text') - $(elt).append(""+ open_text + "") - $(elt).find('.full-custom').click (event) => @toggleFull(event, open_text, close_text) - - # collapsible pattern - el.find('.collapsible header + section').hide() - - # set up triggers - el.find('.full').click (event) => @toggleFull(event, "See full output", "Hide output") - el.find('.collapsible header a').click @toggleHint - - @toggleFull: (event, open_text, close_text) => - event.preventDefault() - parent = $(event.target).parent() - parent.siblings().slideToggle() - parent.parent().toggleClass('open') - if $(event.target).text() == open_text - new_text = close_text - else - new_text = open_text - if $(event.target).hasClass('full') - el = parent.find('.full') - else - el = $(event.target) - el.text(new_text) - - @toggleHint: (event) => - event.preventDefault() - $(event.target).parent().siblings().slideToggle() - $(event.target).parent().parent().toggleClass('open') diff --git a/common/lib/xmodule/xmodule/js/src/collapsible.js b/common/lib/xmodule/xmodule/js/src/collapsible.js new file mode 100644 index 0000000000..e86f30deaf --- /dev/null +++ b/common/lib/xmodule/xmodule/js/src/collapsible.js @@ -0,0 +1,110 @@ +(function (undefined) { + 'use strict'; + + // [module Collapsible] + // + // [description] + // Set of library functions that provide a simple way to add + // collapsible functionality to elements. + this.Collapsible = { + setCollapsibles: setCollapsibles, + toggleFull: toggleFull, + toggleHint: toggleHint + }; + + return; + + // [function setCollapsibles] + // + // [description] + // Scan element's content for generic collapsible containers. + // + // [params] + // el: container + function setCollapsibles(el) { + var linkBottom, linkTop, short_custom; + + linkTop = 'See full output'; + linkBottom = 'See full output'; + + // Standard longform + shortfom pattern. + el.find('.longform').hide(); + el.find('.shortform').append(linkTop, linkBottom); + + // Custom longform + shortform text pattern. + short_custom = el.find('.shortform-custom'); + + // Set up each one individually. + short_custom.each(function (index, elt) { + var close_text, open_text; + + open_text = $(elt).data('open-text'); + close_text = $(elt).data('close-text'); + $(elt).append("" + open_text + ""); + + $(elt).find('.full-custom').click(function (event) { + Collapsible.toggleFull(event, open_text, close_text); + }); + }); + + // Collapsible pattern. + el.find('.collapsible header + section').hide(); + + // Set up triggers. + el.find('.full').click(function (event) { + Collapsible.toggleFull(event, "See full output", "Hide output"); + }); + el.find('.collapsible header a').click(Collapsible.toggleHint); + } + + // [function toggleFull] + // + // [description] + // Toggle the display of full text for a collapsible element. + // + // [params] + // event: jQuery event object associated with the event that + // triggered this callback function. + // open_text: text that should be displayed when the collapsible + // is open. + // close_text: text that should be displayed when the collapsible + // is closed. + function toggleFull(event, open_text, close_text) { + var el, new_text, parent; + + event.preventDefault(); + + parent = $(event.target).parent(); + parent.siblings().slideToggle(); + parent.parent().toggleClass('open'); + + if ($(event.target).text() === open_text) { + new_text = close_text; + } else { + new_text = open_text; + } + + if ($(event.target).hasClass('full')) { + el = parent.find('.full'); + } else { + el = $(event.target); + } + + el.text(new_text); + } + + // [function toggleHint] + // + // [description] + // Toggle the collapsible open to show the hint. + // + // [params] + // event: jQuery event object associated with the event that + // triggered this callback function. + function toggleHint(event) { + event.preventDefault(); + + $(event.target).parent().siblings().slideToggle(); + $(event.target).parent().parent().toggleClass('open'); + } +}).call(this); diff --git a/common/lib/xmodule/xmodule/peer_grading_module.py b/common/lib/xmodule/xmodule/peer_grading_module.py index 11c063e545..e6a30e4450 100644 --- a/common/lib/xmodule/xmodule/peer_grading_module.py +++ b/common/lib/xmodule/xmodule/peer_grading_module.py @@ -100,8 +100,10 @@ class PeerGradingModule(PeerGradingFields, XModule): 'coffee': [ resource_string(__name__, 'js/src/peergrading/peer_grading.coffee'), resource_string(__name__, 'js/src/peergrading/peer_grading_problem.coffee'), - resource_string(__name__, 'js/src/collapsible.coffee'), resource_string(__name__, 'js/src/javascript_loader.coffee'), + ], + 'js': [ + resource_string(__name__, 'js/src/collapsible.js'), ] } js_module_name = "PeerGrading" @@ -718,4 +720,3 @@ class PeerGradingDescriptor(PeerGradingFields, RawDescriptor): show_calibration_essay = module_attr('show_calibration_essay') use_for_single_location_local = module_attr('use_for_single_location_local') _find_corresponding_module_for_location = module_attr('_find_corresponding_module_for_location') - diff --git a/common/lib/xmodule/xmodule/videoannotation_module.py b/common/lib/xmodule/xmodule/videoannotation_module.py index a27eb7c628..5f31509d01 100644 --- a/common/lib/xmodule/xmodule/videoannotation_module.py +++ b/common/lib/xmodule/xmodule/videoannotation_module.py @@ -35,12 +35,16 @@ class AnnotatableFields(object): class VideoAnnotationModule(AnnotatableFields, XModule): '''Video Annotation Module''' - js = {'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee'), - resource_string(__name__, 'js/src/collapsible.coffee'), - resource_string(__name__, 'js/src/html/display.coffee'), - resource_string(__name__, 'js/src/annotatable/display.coffee') - ], - 'js': []} + js = { + 'coffee': [ + resource_string(__name__, 'js/src/javascript_loader.coffee'), + resource_string(__name__, 'js/src/html/display.coffee'), + resource_string(__name__, 'js/src/annotatable/display.coffee'), + ], + 'js': [ + resource_string(__name__, 'js/src/collapsible.js'), + ] + } css = {'scss': [resource_string(__name__, 'css/annotatable/display.scss')]} icon_class = 'videoannotation'