Commit 408726e6 by Calen Pennington

Standardize how JS XModules are instantiated

parent 50f27bcf
......@@ -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
......
......@@ -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'))}"
......
......@@ -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()
......
......@@ -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 <section> 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/<prefix>/...
"""
@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
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')
......
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()
......
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')
......
@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
<section class="xmodule_display" data-type="${module_name}">
${content}
</section>
<section class="xmodule_edit" data-type="${module_name}">
${content}
</section>
......@@ -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)
......
......@@ -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')
......@@ -32,11 +32,3 @@
</ul>
</nav>
</div>
<%block name="js_extra">
<script type="text/javascript">
$(function(){
new Sequence($("#sequence_${element_id}"));
});
</script>
</%block>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment