diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 8205a1ee4d..e1722c0d65 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -14,7 +14,7 @@ from static_replace import replace_urls from mitxmako.shortcuts import render_to_response, render_to_string from xmodule.modulestore.django import modulestore -from xmodule_modifiers import replace_static_urls +from xmodule_modifiers import replace_static_urls, wrap_xmodule # ==== Public views ================================================== @@ -97,6 +97,7 @@ def edit_item(request): raise Http404 # TODO (vshnayder): better error item = modulestore().get_item(item_location) + item.get_html = wrap_xmodule(item.get_html, item, "xmodule_edit.html") return render_to_response('unit.html', { 'contents': item.get_html(), 'js_module': item.js_module_name, @@ -181,7 +182,10 @@ def load_sample_module(descriptor, instance_state, shared_state): """ system = sample_module_system(descriptor) module = descriptor.xmodule_constructor(system)(instance_state, shared_state) - module.get_html = replace_static_urls(module.get_html, module.metadata['data_dir']) + module.get_html = replace_static_urls( + wrap_xmodule(module.get_html, module, "xmodule_display.html"), + module.metadata['data_dir'] + ) return module diff --git a/cms/static/coffee/src/models/module.coffee b/cms/static/coffee/src/models/module.coffee index e8b3bbb108..3abea41e35 100644 --- a/cms/static/coffee/src/models/module.coffee +++ b/cms/static/coffee/src/models/module.coffee @@ -4,20 +4,7 @@ class CMS.Models.Module extends Backbone.Model data: '' loadModule: (element) -> - moduleType = @get('type') - - try - @module = if moduleType? then new window[moduleType](element) else null - catch error - console.error "Unable to load #{moduleType}: #{error.message}" if console - - loadPreview: (element) -> - previewType = @get('previewType') - - try - @previewModule = if previewType? then new window[previewType](element) else null - catch error - console.error "Unable to load #{previewType}: #{error.message}" if console + @module = XModule.loadModule($(element).find('.xmodule_edit')) editUrl: -> "/edit_item?#{$.param(id: @get('id'))}" diff --git a/cms/static/coffee/src/views/module_edit.coffee b/cms/static/coffee/src/views/module_edit.coffee index 2105952b24..515091d958 100644 --- a/cms/static/coffee/src/views/module_edit.coffee +++ b/cms/static/coffee/src/views/module_edit.coffee @@ -10,8 +10,9 @@ class CMS.Views.ModuleEdit extends Backbone.View initialize: -> @$el.load @model.editUrl(), => @model.loadModule(@el) - @$el.find('.preview').children().each (idx, previewEl) => - @model.loadPreview(previewEl) + + # Load preview modules + XModule.loadModules('display') save: (event) -> event.preventDefault() diff --git a/common/djangoapps/xmodule_modifiers.py b/common/djangoapps/xmodule_modifiers.py index a8ef8b5452..a9314f4b43 100644 --- a/common/djangoapps/xmodule_modifiers.py +++ b/common/djangoapps/xmodule_modifiers.py @@ -5,17 +5,38 @@ from static_replace import replace_urls from mitxmako.shortcuts import render_to_string -def replace_static_urls(original, prefix): +def wrap_xmodule(get_html, module, template): + """ + Wraps the results of get_html in a standard
with identifying + data so that the appropriate javascript module can be loaded onto it. + + get_html: An XModule.get_html method or an XModuleDescriptor.get_html method + module: An XModule + template: A template that takes the variables: + content: the results of get_html, + module_name: the js_module_name of the module + """ + + @wraps(get_html) + def _get_html(): + return render_to_string(template, { + 'content': get_html(), + 'module_name': module.js_module_name + }) + return _get_html + + +def replace_static_urls(get_html, prefix): """ Updates the supplied module with a new get_html function that wraps the old get_html function and substitutes urls of the form /static/... with urls that are /static//... """ - @wraps(original) - def get_html(): - return replace_urls(original(), staticfiles_prefix=prefix) - return get_html + @wraps(get_html) + def _get_html(): + return replace_urls(get_html(), staticfiles_prefix=prefix) + return _get_html def grade_histogram(module_id): @@ -40,15 +61,15 @@ def grade_histogram(module_id): return grades -def add_histogram(original, module): +def add_histogram(get_html, module): """ Updates the supplied module with a new get_html function that wraps the output of the old get_html function with additional information for admin users only, including a histogram of student answers and the definition of the xmodule """ - @wraps(original) - def get_html(): + @wraps(get_html) + def _get_html(): module_id = module.id histogram = grade_histogram(module_id) render_histogram = len(histogram) > 0 @@ -73,7 +94,7 @@ def add_histogram(original, module): 'edit_link': edit_link, 'histogram': json.dumps(histogram), 'render_histogram': render_histogram, - 'module_content': original()} + 'module_content': get_html()} return render_to_string("staff_problem_info.html", staff_context) - return get_html + return _get_html diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 1f723e3b06..b5a41e3da5 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -1,6 +1,6 @@ class @Problem constructor: (element) -> - @el = $(element) + @el = $(element).find('.problems-wrapper') @id = @el.data('problem-id') @element_id = @el.attr('id') @url = @el.data('url') diff --git a/common/lib/xmodule/xmodule/js/src/sequence/display.coffee b/common/lib/xmodule/xmodule/js/src/sequence/display.coffee index aef74cf459..0b17111d81 100644 --- a/common/lib/xmodule/xmodule/js/src/sequence/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/sequence/display.coffee @@ -1,7 +1,6 @@ class @Sequence constructor: (element) -> - (@id, @element_id, @elements, position) -> - @el = $(element) + @el = $(element).find('.sequence') @contents = @$('.seq_contents') @id = @el.data('id') @initProgress() @@ -81,12 +80,12 @@ class @Sequence @mark_active new_position @$('#seq_content').html @contents.eq(new_position - 1).text() + XModule.loadModules('display', @$('#seq_content')) MathJax.Hub.Queue(["Typeset", MathJax.Hub]) @position = new_position @toggleArrows() @hookUpProgressEvent() - @el.trigger 'contentChanged' goto: (event) => event.preventDefault() diff --git a/common/lib/xmodule/xmodule/js/src/video/display.coffee b/common/lib/xmodule/xmodule/js/src/video/display.coffee index af5f19fbf7..8057e003da 100644 --- a/common/lib/xmodule/xmodule/js/src/video/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/video/display.coffee @@ -1,10 +1,11 @@ class @Video - constructor: (@element) -> - @id = $(@element).attr('id').replace(/video_/, '') - @caption_data_dir = $(@element).data('caption-data-dir') + constructor: (element) -> + @el = $(element).find('.video') + @id = @el.attr('id').replace(/video_/, '') + @caption_data_dir = @el.data('caption-data-dir') window.player = null @el = $("#video_#{@id}") - @parseVideos $(@element).data('streams') + @parseVideos @el.data('streams') @fetchMetadata() @parseSpeed() $("#video_#{@id}").data('video', this).addClass('video-load-complete') diff --git a/common/static/coffee/src/xmodule.coffee b/common/static/coffee/src/xmodule.coffee new file mode 100644 index 0000000000..56a447c0e6 --- /dev/null +++ b/common/static/coffee/src/xmodule.coffee @@ -0,0 +1,30 @@ +@XModule = + ### + Load a single module (either an edit module or a display module) + from the supplied element, which should have a data-type attribute + specifying the class to load + ### + loadModule: (element) -> + moduleType = $(element).data('type') + if moduleType == 'None' + return + + try + new window[moduleType](element) + catch error + console.error "Unable to load #{moduleType}: #{error.message}" if console + + ### + Load all modules on the page of the specified type. + If container is provided, only load modules inside that element + Type is one of 'display' or 'edit' + ### + loadModules: (type, container) -> + selector = ".xmodule_#{type}" + + if container? + modules = $(container).find(selector) + else + modules = $(selector) + + modules.each (idx, element) -> XModule.loadModule element diff --git a/common/templates/xmodule_display.html b/common/templates/xmodule_display.html new file mode 100644 index 0000000000..09af18ebb8 --- /dev/null +++ b/common/templates/xmodule_display.html @@ -0,0 +1,3 @@ +
+ ${content} +
diff --git a/common/templates/xmodule_edit.html b/common/templates/xmodule_edit.html new file mode 100644 index 0000000000..1828c82987 --- /dev/null +++ b/common/templates/xmodule_edit.html @@ -0,0 +1,3 @@ +
+ ${content} +
diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 699baabe97..3f111c2953 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -13,7 +13,7 @@ from models import StudentModule, StudentModuleCache from static_replace import replace_urls from xmodule.exceptions import NotFoundError from xmodule.x_module import ModuleSystem -from xmodule_modifiers import replace_static_urls, add_histogram +from xmodule_modifiers import replace_static_urls, add_histogram, wrap_xmodule log = logging.getLogger("mitx.courseware") @@ -163,7 +163,10 @@ def get_module(user, request, location, student_module_cache, position=None): module = descriptor.xmodule_constructor(system)(instance_state, shared_state) - module.get_html = replace_static_urls(module.get_html, module.metadata['data_dir']) + module.get_html = replace_static_urls( + wrap_xmodule(module.get_html, module, 'xmodule_display.html'), + module.metadata['data_dir'] + ) if settings.MITX_FEATURES.get('DISPLAY_HISTOGRAMS_TO_STAFF') and user.is_staff: module.get_html = add_histogram(module.get_html) diff --git a/lms/static/coffee/src/courseware.coffee b/lms/static/coffee/src/courseware.coffee index 06e0169cec..1a8910bb28 100644 --- a/lms/static/coffee/src/courseware.coffee +++ b/lms/static/coffee/src/courseware.coffee @@ -5,19 +5,13 @@ class @Courseware Courseware.prefix = $("meta[name='path_prefix']").attr('content') new Navigation Logger.bind() - @bind() @render() @start: -> new Courseware - bind: -> - $('.course-content .sequence, .course-content .tab') - .bind 'contentChanged', @render - render: -> - $('.course-content .video').each (idx, element) -> new Video element - $('.course-content .problems-wrapper').each (idx, element) -> new Problem element + XModule.loadModules('display') $('.course-content .histogram').each -> id = $(this).attr('id').replace(/histogram_/, '') new Histogram id, $(this).data('histogram') diff --git a/lms/templates/seq_module.html b/lms/templates/seq_module.html index 9d505b687c..42953c40c6 100644 --- a/lms/templates/seq_module.html +++ b/lms/templates/seq_module.html @@ -32,11 +32,3 @@ - -<%block name="js_extra"> - -