diff --git a/cms/djangoapps/contentstore/features/component.py b/cms/djangoapps/contentstore/features/component.py index f8425a3600..e99f6e2ae5 100644 --- a/cms/djangoapps/contentstore/features/component.py +++ b/cms/djangoapps/contentstore/features/component.py @@ -42,7 +42,7 @@ def add_a_multi_step_component(step, is_advanced, category): def see_a_multi_step_component(step, category): # Wait for all components to finish rendering - selector = 'li.component section.xmodule_display' + selector = 'li.component section.xblock-student_view' world.wait_for(lambda _: len(world.css_find(selector)) == len(step.hashes)) for idx, step_hash in enumerate(step.hashes): diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index 12df3fcf7a..2d9a66be1e 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -8,7 +8,7 @@ from django.core.urlresolvers import reverse from django.contrib.auth.decorators import login_required from mitxmako.shortcuts import render_to_response, render_to_string -from xmodule_modifiers import replace_static_urls, wrap_xmodule +from xmodule_modifiers import replace_static_urls, wrap_xblock from xmodule.error_module import ErrorDescriptor from xmodule.errortracker import exc_info_to_str from xmodule.exceptions import NotFoundError, ProcessingError @@ -77,7 +77,7 @@ def preview_component(request, location): component = modulestore().get_item(location) # Wrap the generated fragment in the xmodule_editor div so that the javascript # can bind to it correctly - component.runtime.wrappers.append(partial(wrap_xmodule, 'xmodule_edit.html')) + component.runtime.wrappers.append(wrap_xblock) try: content = component.render('studio_view').content @@ -105,11 +105,6 @@ def preview_module_system(request, preview_id, descriptor): course_id = get_course_for_item(descriptor.location).location.course_id - if descriptor.location.category == 'static_tab': - wrapper_template = 'xmodule_tab_display.html' - else: - wrapper_template = 'xmodule_display.html' - return ModuleSystem( static_url=settings.STATIC_URL, ajax_url=reverse('preview_dispatch', args=[preview_id, descriptor.location.url(), '']).rstrip('/'), @@ -129,7 +124,7 @@ def preview_module_system(request, preview_id, descriptor): # Set up functions to modify the fragment produced by student_view wrappers=( # This wrapper wraps the module in the template specified above - partial(wrap_xmodule, wrapper_template), + partial(wrap_xblock, display_name_only=descriptor.location.category == 'static_tab'), # This wrapper replaces urls in the output that start with /static # with the correct course-specific url for the static content diff --git a/cms/static/coffee/spec/main.coffee b/cms/static/coffee/spec/main.coffee index 4251307892..aba1e5405a 100644 --- a/cms/static/coffee/spec/main.coffee +++ b/cms/static/coffee/spec/main.coffee @@ -16,6 +16,7 @@ requirejs.config({ "jquery.fileupload": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload", "jquery.iframe-transport": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport", "jquery.inputnumber": "xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill", + "jquery.immediateDescendents": "xmodule_js/common_static/coffee/src/jquery.immediateDescendents", "datepair": "xmodule_js/common_static/js/vendor/timepicker/datepair", "date": "xmodule_js/common_static/js/vendor/date", "underscore": "xmodule_js/common_static/js/vendor/underscore-min", @@ -25,6 +26,7 @@ requirejs.config({ "tinymce": "xmodule_js/common_static/js/vendor/tiny_mce/tiny_mce", "jquery.tinymce": "xmodule_js/common_static/js/vendor/tiny_mce/jquery.tinymce", "xmodule": "xmodule_js/src/xmodule", + "xblock": "xmodule_js/common_static/coffee/src/xblock", "utility": "xmodule_js/common_static/js/src/utility", "sinon": "xmodule_js/common_static/js/vendor/sinon-1.7.1", "squire": "xmodule_js/common_static/js/vendor/Squire", @@ -129,6 +131,14 @@ requirejs.config({ deps: ["jasmine"], exports: "AsyncSpec" }, + "xblock/core": { + exports: "XBlock", + deps: ["jquery", "jquery.immediateDescendents"] + }, + "xblock/runtime.v1": { + exports: "XBlock", + deps: ["xblock/core"] + }, "coffee/src/main": { deps: ["coffee/src/ajax_prefix"] diff --git a/cms/static/coffee/spec/main_squire.coffee b/cms/static/coffee/spec/main_squire.coffee index ee23792509..928e10c61f 100644 --- a/cms/static/coffee/spec/main_squire.coffee +++ b/cms/static/coffee/spec/main_squire.coffee @@ -16,6 +16,7 @@ requirejs.config({ "jquery.fileupload": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload", "jquery.iframe-transport": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport", "jquery.inputnumber": "xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill", + "jquery.immediateDescendents": "xmodule_js/common_static/coffee/src/jquery.immediateDescendents", "datepair": "xmodule_js/common_static/js/vendor/timepicker/datepair", "date": "xmodule_js/common_static/js/vendor/date", "underscore": "xmodule_js/common_static/js/vendor/underscore-min", @@ -25,6 +26,7 @@ requirejs.config({ "tinymce": "xmodule_js/common_static/js/vendor/tiny_mce/tiny_mce", "jquery.tinymce": "xmodule_js/common_static/js/vendor/tiny_mce/jquery.tinymce", "xmodule": "xmodule_js/src/xmodule", + "xblock": "xmodule_js/common_static/coffee/src/xblock", "utility": "xmodule_js/common_static/js/src/utility", "sinon": "xmodule_js/common_static/js/vendor/sinon-1.7.1", "squire": "xmodule_js/common_static/js/vendor/Squire", @@ -129,6 +131,14 @@ requirejs.config({ deps: ["jasmine"], exports: "AsyncSpec" }, + "xblock/core": { + exports: "XBlock", + deps: ["jquery", "jquery.immediateDescendents"] + }, + "xblock/runtime.v1": { + exports: "XBlock", + deps: ["xblock/core"] + }, "coffee/src/main": { deps: ["coffee/src/ajax_prefix"] diff --git a/cms/static/coffee/spec/views/module_edit_spec.coffee b/cms/static/coffee/spec/views/module_edit_spec.coffee index 157fb18e6a..f108e5046e 100644 --- a/cms/static/coffee/spec/views/module_edit_spec.coffee +++ b/cms/static/coffee/spec/views/module_edit_spec.coffee @@ -19,7 +19,7 @@ define ["coffee/src/views/module_edit", "xmodule"], (ModuleEdit) -> Delete -
+
@@ -66,10 +66,9 @@ define ["coffee/src/views/module_edit", "xmodule"], (ModuleEdit) -> describe "loadDisplay", -> beforeEach -> - spyOn(XModule, 'loadModule') + spyOn(XBlock, 'initializeBlock') @moduleEdit.loadDisplay() it "loads the .xmodule-display inside the module editor", -> - expect(XModule.loadModule).toHaveBeenCalled() - expect(XModule.loadModule.mostRecentCall.args[0]).toBe($('.xmodule_display')) - + expect(XBlock.initializeBlock).toHaveBeenCalled() + expect(XBlock.initializeBlock.mostRecentCall.args[0]).toBe($('.xblock-student_view')) diff --git a/cms/static/coffee/src/views/module_edit.coffee b/cms/static/coffee/src/views/module_edit.coffee index 041fc97c47..2b6cdcec0b 100644 --- a/cms/static/coffee/src/views/module_edit.coffee +++ b/cms/static/coffee/src/views/module_edit.coffee @@ -1,7 +1,7 @@ -define ["backbone", "jquery", "underscore", "gettext", "xmodule", +define ["backbone", "jquery", "underscore", "gettext", "xblock/runtime.v1", "js/views/feedback_notification", "js/views/metadata", "js/collections/metadata" - "jquery.inputnumber"], -(Backbone, $, _, gettext, XModule, NotificationView, MetadataView, MetadataCollection) -> + "jquery.inputnumber", "xmodule"], +(Backbone, $, _, gettext, XBlock, NotificationView, MetadataView, MetadataCollection) -> class ModuleEdit extends Backbone.View tagName: 'li' className: 'component' @@ -21,11 +21,11 @@ define ["backbone", "jquery", "underscore", "gettext", "xmodule", $component_editor: => @$el.find('.component-editor') loadDisplay: -> - XModule.loadModule(@$el.find('.xmodule_display')) + XBlock.initializeBlock(@$el.find('.xblock-student_view')) loadEdit: -> if not @module - @module = XModule.loadModule(@$el.find('.xmodule_edit')) + @module = XBlock.initializeBlock(@$el.find('.xblock-studio_view')) # At this point, metadata-edit.html will be loaded, and the metadata (as JSON) is available. metadataEditor = @$el.find('.metadata_edit') metadataData = metadataEditor.data('metadata') diff --git a/cms/static/js_test.yml b/cms/static/js_test.yml index 0e163b61d1..3a85b3a3cf 100644 --- a/cms/static/js_test.yml +++ b/cms/static/js_test.yml @@ -54,6 +54,8 @@ lib_paths: - xmodule_js/common_static/js/vendor/date.js - xmodule_js/common_static/js/vendor/domReady.js - xmodule_js/common_static/js/vendor/jquery.smooth-scroll.min.js + - xmodule_js/common_static/coffee/src/jquery.immediateDescendents.js + - xmodule_js/common_static/coffee/src/xblock # Paths to source JavaScript files src_paths: diff --git a/cms/static/js_test_squire.yml b/cms/static/js_test_squire.yml index 2284319997..2b37e4792f 100644 --- a/cms/static/js_test_squire.yml +++ b/cms/static/js_test_squire.yml @@ -49,6 +49,7 @@ lib_paths: - xmodule_js/common_static/js/vendor/jasmine.async.js - xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js - xmodule_js/src/xmodule.js + - xmodule_js/common_static/coffee/src/jquery.immediateDescendents.js - xmodule_js/common_static/js/test/i18n.js # Paths to source JavaScript files diff --git a/cms/templates/base.html b/cms/templates/base.html index ff2fcf9b01..04aa735747 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -54,6 +54,7 @@ var require = { "jquery.fileupload": "js/vendor/jQuery-File-Upload/js/jquery.fileupload", "jquery.iframe-transport": "js/vendor/jQuery-File-Upload/js/jquery.iframe-transport", "jquery.inputnumber": "js/vendor/html5-input-polyfills/number-polyfill", + "jquery.immediateDescendents": "coffee/src/jquery.immediateDescendents", "datepair": "js/vendor/timepicker/datepair", "date": "js/vendor/date", "tzAbbr": "js/vendor/tzAbbr", @@ -64,6 +65,7 @@ var require = { "tinymce": "js/vendor/tiny_mce/tiny_mce", "jquery.tinymce": "js/vendor/tiny_mce/jquery.tinymce", "xmodule": "/xmodule/xmodule", + "xblock": "coffee/src/xblock", "utility": "js/src/utility", "draggabilly": "js/vendor/draggabilly.pkgd", @@ -159,6 +161,14 @@ var require = { "mathjax": { exports: "MathJax" }, + "xblock/core": { + exports: "XBlock", + deps: ["jquery", "jquery.immediateDescendents"] + }, + "xblock/runtime.v1": { + exports: "XBlock", + deps: ["xblock/core"] + }, "coffee/src/main": { deps: ["coffee/src/ajax_prefix"] diff --git a/cms/templates/xmodule_tab_display.html b/cms/templates/xmodule_tab_display.html deleted file mode 100644 index 3b6ecc9593..0000000000 --- a/cms/templates/xmodule_tab_display.html +++ /dev/null @@ -1,3 +0,0 @@ -
- ${display_name} -
diff --git a/common/djangoapps/terrain/ui_helpers.py b/common/djangoapps/terrain/ui_helpers.py index be52c4bd3d..30d2452908 100644 --- a/common/djangoapps/terrain/ui_helpers.py +++ b/common/djangoapps/terrain/ui_helpers.py @@ -115,6 +115,7 @@ def wait_for_js_variable_truthy(variable): def wait_for_xmodule(): "Wait until the XModule Javascript has loaded on the page." world.wait_for_js_variable_truthy("XModule") + world.wait_for_js_variable_truthy("XBlock") @world.absorb diff --git a/common/djangoapps/xmodule_modifiers.py b/common/djangoapps/xmodule_modifiers.py index 43942f3edf..50e98ee994 100644 --- a/common/djangoapps/xmodule_modifiers.py +++ b/common/djangoapps/xmodule_modifiers.py @@ -14,6 +14,7 @@ from xblock.fragment import Fragment from xmodule.seq_module import SequenceModule from xmodule.vertical_module import VerticalModule +from xmodule.x_module import shim_xmodule_js, XModuleDescriptor, XModule log = logging.getLogger(__name__) @@ -28,32 +29,50 @@ def wrap_fragment(fragment, new_content): return wrapper_frag -def wrap_xmodule(template, block, view, frag, context): # pylint: disable=unused-argument +def wrap_xblock(block, view, frag, context, display_name_only=False): # pylint: disable=unused-argument """ - Wraps the results of get_html in a standard
with identifying + Wraps the results of rendering an XBlock view 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, - display_name: the display name of the xmodule, if available (None otherwise) - class_: the module class name - module_name: the js_module_name of the module + :param block: An XBlock (that may be an XModule or XModuleDescriptor) + :param view: The name of the view that rendered the fragment being wrapped + :param frag: The :class:`Fragment` to be wrapped + :param context: The context passed to the view being rendered + :param display_name_only: If true, don't render the fragment content at all. + Instead, just render the `display_name` of `block` """ - # If XBlock generated this class, then use the first baseclass - # as the name (since that's the original, unmixed class) + # If any mixins have been applied, then use the unmixed class class_name = getattr(block, 'unmixed_class', block.__class__).__name__ + data = {} + css_classes = ['xblock', 'xblock-' + view] + + if isinstance(block, (XModule, XModuleDescriptor)): + if view == 'student_view': + # The block is acting as an XModule + css_classes.append('xmodule_display') + elif view == 'studio_view': + # The block is acting as an XModuleDescriptor + css_classes.append('xmodule_edit') + + css_classes.append('xmodule_' + class_name) + data['type'] = block.js_module_name + shim_xmodule_js(frag) + + if frag.js_init_fn: + data['init'] = frag.js_init_fn + data['runtime-version'] = frag.js_init_version + data['usage-id'] = block.scope_ids.usage_id + data['block-type'] = block.scope_ids.block_type + template_context = { - 'content': frag.content, - 'display_name': block.display_name, - 'class_': class_name, - 'module_name': block.js_module_name, + 'content': block.display_name if display_name_only else frag.content, + 'classes': css_classes, + 'data_attributes': ' '.join('data-{}="{}"'.format(key, value) for key, value in data.items()), } - return wrap_fragment(frag, render_to_string(template, template_context)) + return wrap_fragment(frag, render_to_string('xblock_wrapper.html', template_context)) def replace_jump_to_id_urls(course_id, jump_to_id_base_url, block, view, frag, context): # pylint: disable=unused-argument diff --git a/common/lib/xmodule/xmodule/js/fixtures/annotatable.html b/common/lib/xmodule/xmodule/js/fixtures/annotatable.html index 61020d95e8..04b61ce9ee 100644 --- a/common/lib/xmodule/xmodule/js/fixtures/annotatable.html +++ b/common/lib/xmodule/xmodule/js/fixtures/annotatable.html @@ -1,4 +1,4 @@ -
+
First Annotation Exercise
diff --git a/common/lib/xmodule/xmodule/js/fixtures/combined-open-ended.html b/common/lib/xmodule/xmodule/js/fixtures/combined-open-ended.html index e5eb0858f7..ae2c195a85 100644 --- a/common/lib/xmodule/xmodule/js/fixtures/combined-open-ended.html +++ b/common/lib/xmodule/xmodule/js/fixtures/combined-open-ended.html @@ -1,5 +1,5 @@
-
+

Problem 1

@@ -8,7 +8,7 @@
Step 1 (Problem complete) : 1 / 1 - +
Step 2 (Being scored) : None / 1 @@ -109,14 +109,14 @@ location = i4x://MITx/6.002x/combinedopenended/CombinedOE github = https://github.com/MITx/content-mit-6002x/tree/master/combinedopenended/CombinedOE.xml definition =
None
metadata = { - "showanswer": "attempted", - "display_name": "Problem 1", - "graceperiod": "1 day 12 hours 59 minutes 59 seconds", - "xqa_key": "KUBrWtK3RAaBALLbccHrXeD3RHOpmZ2A", - "rerandomize": "never", - "start": "2012-09-05T12:00", - "attempts": "10000", - "data_dir": "content-mit-6002x", + "showanswer": "attempted", + "display_name": "Problem 1", + "graceperiod": "1 day 12 hours 59 minutes 59 seconds", + "xqa_key": "KUBrWtK3RAaBALLbccHrXeD3RHOpmZ2A", + "rerandomize": "never", + "start": "2012-09-05T12:00", + "attempts": "10000", + "data_dir": "content-mit-6002x", "max_score": "1" } category = CombinedOpenEndedModule diff --git a/common/lib/xmodule/xmodule/js/fixtures/crowdsource_hinter.html b/common/lib/xmodule/xmodule/js/fixtures/crowdsource_hinter.html index e8d327a514..e390685fc7 100644 --- a/common/lib/xmodule/xmodule/js/fixtures/crowdsource_hinter.html +++ b/common/lib/xmodule/xmodule/js/fixtures/crowdsource_hinter.html @@ -1,10 +1,10 @@
  • -
    +
    -
    +
    diff --git a/common/lib/xmodule/xmodule/js/fixtures/problem.html b/common/lib/xmodule/xmodule/js/fixtures/problem.html index 07e147a9e7..c64b8b995e 100644 --- a/common/lib/xmodule/xmodule/js/fixtures/problem.html +++ b/common/lib/xmodule/xmodule/js/fixtures/problem.html @@ -1,7 +1,7 @@ -
    -
    +
    \ No newline at end of file diff --git a/common/lib/xmodule/xmodule/js/spec/annotatable/display_spec.coffee b/common/lib/xmodule/xmodule/js/spec/annotatable/display_spec.coffee index bed2e0442a..dc49575f63 100644 --- a/common/lib/xmodule/xmodule/js/spec/annotatable/display_spec.coffee +++ b/common/lib/xmodule/xmodule/js/spec/annotatable/display_spec.coffee @@ -2,7 +2,7 @@ describe 'Annotatable', -> beforeEach -> loadFixtures 'annotatable.html' describe 'constructor', -> - el = $('.xmodule_display.xmodule_AnnotatableModule') + el = $('.xblock-student_view.xmodule_AnnotatableModule') beforeEach -> @annotatable = new Annotatable(el) it 'works', -> diff --git a/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee b/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee index 99344c2983..7debc16af1 100644 --- a/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee +++ b/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee @@ -25,7 +25,7 @@ describe 'Problem', -> it 'set the element from html', -> @problem999 = new Problem (" -
    +
    expect(@problem999.element_id).toBe 'problem_999' it 'set the element from loadFixtures', -> - @problem1 = new Problem($('.xmodule_display')) + @problem1 = new Problem($('.xblock-student_view')) expect(@problem1.element_id).toBe 'problem_1' describe 'bind', -> beforeEach -> spyOn window, 'update_schematics' MathJax.Hub.getAllJax.andReturn [@stubbedJax] - @problem = new Problem($('.xmodule_display')) + @problem = new Problem($('.xblock-student_view')) it 'set mathjax typeset', -> expect(MathJax.Hub.Queue).toHaveBeenCalled() @@ -78,7 +78,7 @@ describe 'Problem', -> describe 'renderProgressState', -> beforeEach -> - @problem = new Problem($('.xmodule_display')) + @problem = new Problem($('.xblock-student_view')) #@renderProgressState = @problem.renderProgressState describe 'with a status of "none"', -> @@ -97,7 +97,7 @@ describe 'Problem', -> describe 'render', -> beforeEach -> - @problem = new Problem($('.xmodule_display')) + @problem = new Problem($('.xblock-student_view')) @bind = @problem.bind spyOn @problem, 'bind' @@ -130,7 +130,7 @@ describe 'Problem', -> describe 'check', -> beforeEach -> - @problem = new Problem($('.xmodule_display')) + @problem = new Problem($('.xblock-student_view')) @problem.answers = 'foo=1&bar=2' it 'log the problem_check event', -> @@ -177,7 +177,7 @@ describe 'Problem', -> describe 'reset', -> beforeEach -> - @problem = new Problem($('.xmodule_display')) + @problem = new Problem($('.xblock-student_view')) it 'log the problem_reset event', -> @problem.answers = 'foo=1&bar=2' @@ -198,7 +198,7 @@ describe 'Problem', -> describe 'show', -> beforeEach -> - @problem = new Problem($('.xmodule_display')) + @problem = new Problem($('.xblock-student_view')) @problem.el.prepend '
    ' describe 'when the answer has not yet shown', -> @@ -331,7 +331,7 @@ describe 'Problem', -> describe 'save', -> beforeEach -> - @problem = new Problem($('.xmodule_display')) + @problem = new Problem($('.xblock-student_view')) @problem.answers = 'foo=1&bar=2' it 'log the problem_save event', -> @@ -353,7 +353,7 @@ describe 'Problem', -> describe 'refreshMath', -> beforeEach -> - @problem = new Problem($('.xmodule_display')) + @problem = new Problem($('.xblock-student_view')) $('#input_example_1').val 'E=mc^2' @problem.refreshMath target: $('#input_example_1').get(0) @@ -363,7 +363,7 @@ describe 'Problem', -> describe 'updateMathML', -> beforeEach -> - @problem = new Problem($('.xmodule_display')) + @problem = new Problem($('.xblock-student_view')) @stubbedJax.root.toMathML.andReturn '' describe 'when there is no exception', -> @@ -383,7 +383,7 @@ describe 'Problem', -> describe 'refreshAnswers', -> beforeEach -> - @problem = new Problem($('.xmodule_display')) + @problem = new Problem($('.xblock-student_view')) @problem.el.html '''