diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py index 1be6ac2822..8b8c289da3 100644 --- a/cms/djangoapps/contentstore/views/component.py +++ b/cms/djangoapps/contentstore/views/component.py @@ -46,7 +46,12 @@ COMPONENT_TYPES = ['discussion', 'html', 'problem', 'video'] OPEN_ENDED_COMPONENT_TYPES = ["combinedopenended", "peergrading"] NOTE_COMPONENT_TYPES = ['notes'] -ADVANCED_COMPONENT_TYPES = ['annotatable', 'word_cloud', 'videoalpha'] + OPEN_ENDED_COMPONENT_TYPES + NOTE_COMPONENT_TYPES +ADVANCED_COMPONENT_TYPES = [ + 'annotatable', + 'word_cloud', + 'videoalpha', + 'graphical_slider_tool' +] + OPEN_ENDED_COMPONENT_TYPES + NOTE_COMPONENT_TYPES ADVANCED_COMPONENT_CATEGORY = 'advanced' ADVANCED_COMPONENT_POLICY_KEY = 'advanced_modules' diff --git a/common/lib/xmodule/xmodule/css/gst/display.scss b/common/lib/xmodule/xmodule/css/gst/display.scss new file mode 100644 index 0000000000..83ca4650f0 --- /dev/null +++ b/common/lib/xmodule/xmodule/css/gst/display.scss @@ -0,0 +1,44 @@ +// In the LMS sliders use built-in styles from jquery-ui-1.8.22.custom.css. +// CMS uses its own sliders styles. +// These styles we use only to sure, that slider in GST module +// will be render correctly (just like a duplication some from jquery-ui-1.8.22.custom.css). +// Cause, for example, CMS overwrites many jquery-ui-1.8.22.custom.css styles, +// and we must overwrite them again. + +.ui-widget-content { + border: 1px solid #dddddd; + color: #333333; +} + +.ui-widget { + font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; + font-size: 1.1em; +} + +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { + -moz-border-radius-topleft: 4px; + -webkit-border-top-left-radius: 4px; + -khtml-border-top-left-radius: 4px; + border-top-left-radius: 4px; +} + +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { + -moz-border-radius-topright: 4px; + -webkit-border-top-right-radius: 4px; + -khtml-border-top-right-radius: 4px; + border-top-right-radius: 4px; +} + +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { + -moz-border-radius-bottomleft: 4px; + -webkit-border-bottom-left-radius: 4px; + -khtml-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { + -moz-border-radius-bottomright: 4px; + -webkit-border-bottom-right-radius: 4px; + -khtml-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; +} \ No newline at end of file diff --git a/common/lib/xmodule/xmodule/gst_module.py b/common/lib/xmodule/xmodule/gst_module.py index 5c902f48c2..d6516d92ef 100644 --- a/common/lib/xmodule/xmodule/gst_module.py +++ b/common/lib/xmodule/xmodule/gst_module.py @@ -9,17 +9,16 @@ from lxml import etree from lxml import html import xmltodict -from xmodule.mako_module import MakoModuleDescriptor +from xmodule.editing_module import XMLEditingDescriptor from xmodule.xml_module import XmlDescriptor from xmodule.x_module import XModule from xmodule.stringify import stringify_children from pkg_resources import resource_string from xblock.core import String, Scope - log = logging.getLogger(__name__) -DEFAULT_RENDER=""" +DEFAULT_RENDER = """

Graphic slider tool: Dynamic range and implicit functions.

You can make the range of the x axis (but not ticks of x axis) of @@ -33,13 +32,19 @@ DEFAULT_RENDER=""" """ -DEFAULT_CONFIGURATION=""" + +DEFAULT_CONFIGURATION = """ Math.sqrt(r * r - x * x) -Math.sqrt(r * r - x * x) + Math.sqrt(r * r / 20 - Math.pow(x-r/2.5, 2)) + r/8 + -Math.sqrt(r * r / 20 - Math.pow(x-r/2.5, 2)) + r/5.5 + Math.sqrt(r * r / 20 - Math.pow(x+r/2.5, 2)) + r/8 + -Math.sqrt(r * r / 20 - Math.pow(x+r/2.5, 2)) + r/5.5 + -Math.sqrt(r * r / 5 - x * x) - r/5.5 @@ -54,10 +59,13 @@ DEFAULT_CONFIGURATION=""" """ - class GraphicalSliderToolFields(object): - render = String(scope=Scope.content, default=DEFAULT_RENDER) - configuration = String(scope=Scope.content, default=DEFAULT_CONFIGURATION) + data = String( + help="Html contents to display for this module", + default='{}{}'.format( + DEFAULT_RENDER, DEFAULT_CONFIGURATION), + scope=Scope.content + ) class GraphicalSliderToolModule(GraphicalSliderToolFields, XModule): @@ -65,40 +73,54 @@ class GraphicalSliderToolModule(GraphicalSliderToolFields, XModule): ''' js = { - 'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee')], - 'js': [ - # 3rd party libraries used by graphic slider tool. - # TODO - where to store them - outside xmodule? - resource_string(__name__, 'js/src/graphical_slider_tool/gst_main.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/state.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/logme.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/general_methods.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/sliders.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/inputs.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/graph.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/el_output.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/g_label_el_output.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/gst.js') - - ] + 'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee')], + 'js': [ + # 3rd party libraries used by graphic slider tool. + # TODO - where to store them - outside xmodule? + resource_string(__name__, 'js/src/graphical_slider_tool/gst_main.js'), + resource_string(__name__, 'js/src/graphical_slider_tool/state.js'), + resource_string(__name__, 'js/src/graphical_slider_tool/logme.js'), + resource_string(__name__, 'js/src/graphical_slider_tool/general_methods.js'), + resource_string(__name__, 'js/src/graphical_slider_tool/sliders.js'), + resource_string(__name__, 'js/src/graphical_slider_tool/inputs.js'), + resource_string(__name__, 'js/src/graphical_slider_tool/graph.js'), + resource_string(__name__, 'js/src/graphical_slider_tool/el_output.js'), + resource_string(__name__, 'js/src/graphical_slider_tool/g_label_el_output.js'), + resource_string(__name__, 'js/src/graphical_slider_tool/gst.js') + ] } + css = {'scss': [resource_string(__name__, 'css/gst/display.scss')]} js_module_name = "GraphicalSliderTool" + @property + def configuration(self): + return stringify_children( + html.fromstring(self.data).xpath('configuration')[0] + ) + + @property + def render(self): + return stringify_children( + html.fromstring(self.data).xpath('render')[0] + ) + def get_html(self): """ Renders parameters to template. """ # these 3 will be used in class methods self.html_id = self.location.html_id() self.html_class = self.location.category + self.configuration_json = self.build_configuration_json() params = { - 'gst_html': self.substitute_controls(self.render), - 'element_id': self.html_id, - 'element_class': self.html_class, - 'configuration_json': self.configuration_json - } + 'gst_html': self.substitute_controls(self.render), + 'element_id': self.html_id, + 'element_class': self.html_class, + 'configuration_json': self.configuration_json + } content = self.system.render_template( - 'graphical_slider_tool.html', params) + 'graphical_slider_tool.html', params + ) return content def substitute_controls(self, html_string): @@ -126,9 +148,10 @@ class GraphicalSliderToolModule(GraphicalSliderToolFields, XModule): if plot_el: plot_el = plot_el[0] plot_el.getparent().replace(plot_el, html.fromstring( - plot_div.format(element_class=self.html_class, - element_id=self.html_id, - style=plot_el.get('style', "")))) + plot_div.format( + element_class=self.html_class, + element_id=self.html_id, + style=plot_el.get('style', "")))) # substitute sliders slider_div = '

added for interface compatibility with xmltodict.parse # class added for javascript's part purposes - return json.dumps(xmltodict.parse('' + self.configuration + '')) + root = '{}'.format( + self.html_class, + self.configuration) + return json.dumps(xmltodict.parse(root)) -class GraphicalSliderToolDescriptor(GraphicalSliderToolFields, MakoModuleDescriptor, XmlDescriptor): +class GraphicalSliderToolDescriptor(GraphicalSliderToolFields, XMLEditingDescriptor, XmlDescriptor): module_class = GraphicalSliderToolModule @classmethod @@ -202,24 +229,14 @@ class GraphicalSliderToolDescriptor(GraphicalSliderToolFields, MakoModuleDescrip exactly one '{0}' tag".format(child)) # finished - def parse(k): - """Assumes that xml_object has child k""" - return stringify_children(xml_object.xpath(k)[0]) return { - 'render': parse('render'), - 'configuration': parse('configuration') - }, [] + 'data': stringify_children(xml_object) + }, [] def definition_to_xml(self, resource_fs): '''Return an xml element representing this definition.''' - xml_object = etree.Element('graphical_slider_tool') - - def add_child(k): - child_str = '<{tag}>{body}'.format(tag=k, body=getattr(self, k)) - child_node = etree.fromstring(child_str) - xml_object.append(child_node) - - for child in ['render', 'configuration']: - add_child(child) - + data = '<{tag}>{body}'.format( + tag='graphical_slider_tool', + body=self.data) + xml_object = etree.fromstring(data) return xml_object diff --git a/common/lib/xmodule/xmodule/tests/test_import.py b/common/lib/xmodule/xmodule/tests/test_import.py index 2fe9d70627..fb1bed2d3a 100644 --- a/common/lib/xmodule/xmodule/tests/test_import.py +++ b/common/lib/xmodule/xmodule/tests/test_import.py @@ -445,7 +445,7 @@ class ImportTestCase(BaseCourseTestCase): render_string_from_sample_gst_xml = """ \ """.strip() - self.assertEqual(gst_sample.render, render_string_from_sample_gst_xml) + self.assertIn(render_string_from_sample_gst_xml, gst_sample.data) def test_word_cloud_import(self): modulestore = XMLModuleStore(DATA_DIR, course_dirs=['word_cloud']) diff --git a/common/templates/courseware_vendor_js.html b/common/templates/courseware_vendor_js.html index 84e682ddac..20466210b8 100644 --- a/common/templates/courseware_vendor_js.html +++ b/common/templates/courseware_vendor_js.html @@ -8,6 +8,7 @@ + ## codemirror