Commit 1b960e3e by Ehtesham Committed by muzaffaryousaf

requiring codemirror compressed with all addons included

parent f91583c2
......@@ -28,6 +28,7 @@
'mustache': 'js/vendor/mustache',
'codemirror': 'js/vendor/codemirror-compressed',
'codemirror/stex': 'js/vendor/CodeMirror/stex',
'pretty-print': 'js/lib/pretty-print',
'jquery': 'common/js/vendor/jquery',
'jquery-migrate': 'common/js/vendor/jquery-migrate',
'jquery.ui': 'js/vendor/jquery-ui.min',
......
......@@ -6,9 +6,8 @@
## and attach them to the global context manually.
define(["jquery", "underscore", "codemirror", "tinymce",
"jquery.tinymce", "jquery.qtip", "jquery.scrollTo", "jquery.flot",
"jquery.cookie",
"utility"],
function($, _, CodeMirror, tinymce) {
"jquery.cookie", "pretty-print", "utility"],
function($, _, CodeMirror) {
window.$ = $;
window._ = _;
require(['mathjax']);
......
......@@ -36,14 +36,14 @@ from capa.safe_exec import safe_exec
# extra things displayed after "show answers" is pressed
solution_tags = ['solution']
# fully accessible capa response types
ACCESSIBLE_CAPA_RESPONSE_TYPES = [
'choiceresponse',
'multiplechoiceresponse',
'optionresponse',
'numericalresponse',
'stringresponse',
'formularesponse',
# fully accessible capa input types
ACCESSIBLE_CAPA_INPUT_TYPES = [
'checkboxgroup',
'radiogroup',
'choicegroup',
'optioninput',
'textline',
'formulaequationinput',
]
# these get captured as student responses
......@@ -911,6 +911,10 @@ class LoncapaProblem(object):
responsetype_id (str): responsetype id
problem_data (dict): dict to be filled with response data
"""
# if there are no inputtypes then don't do anything
if not inputfields:
return
element_to_be_deleted = None
label = ''
......@@ -938,35 +942,17 @@ class LoncapaProblem(object):
# store <label> tag containing question text to delete
# it later otherwise question will be rendered twice
element_to_be_deleted = responsetype_label_tag
elif 'label' in inputfields[0].attrib:
# Extract label value from label attribute
# This is the case when we have a problem
# * with multiple questions without separation
# * single question with old XML format only
label = inputfields[0].attrib['label']
# Get first <p> tag before responsetype, this <p> contains the question text.
p_tag = response.xpath('preceding-sibling::p[1]')
if p_tag:
# It may be possible that label attribute value doesn't match with <p> tag
# This happens when author updated the question <p> tag directly in XML but
# didn't changed the label attribute value. In this case we will consider the
# first <p> tag before responsetype as question.
if label != p_tag[0].text:
label = p_tag[0].text
element_to_be_deleted = p_tag[0]
else:
elif 'label' not in inputfields[0].attrib:
# In this case the problems don't have tag or label attribute inside the responsetype
# so we will get the first preceding label tag w.r.t to this responsetype.
# This will take care of those multi-question problems that are not using --- in their markdown.
label_tag = response.xpath("preceding-sibling::label[1]")
label_tag = response.xpath('preceding-sibling::label[1]')
if label_tag:
label = label_tag[0].text
element_to_be_deleted = label_tag[0]
# delete label or p element only if responsetype is fully accessible
if response.tag in ACCESSIBLE_CAPA_RESPONSE_TYPES and element_to_be_deleted is not None:
# delete label or p element only if inputtype is fully accessible
if inputfields[0].tag in ACCESSIBLE_CAPA_INPUT_TYPES and element_to_be_deleted is not None:
element_to_be_deleted.getparent().remove(element_to_be_deleted)
# Extract descriptions and set unique id on each description tag
......@@ -981,6 +967,6 @@ class LoncapaProblem(object):
description_id += 1
problem_data[inputfields[0].get('id')] = {
'label': label,
'label': label.strip() if label else '',
'descriptions': descriptions
}
......@@ -96,10 +96,13 @@ class Status(object):
'correct': _('This answer is correct.'),
'incorrect': _('This answer is incorrect.'),
'partially-correct': _('This answer is partially correct.'),
'unanswered': _('This answer is unanswered.'),
'unsubmitted': _('This answer is unanswered.'),
'queued': _('This answer is being processed.'),
}
tooltips.update(
dict.fromkeys(
['incomplete', 'unanswered', 'unsubmitted'], _('Not yet answered.')
)
)
self.display_name = names.get(status, unicode(status))
self.display_tooltip = tooltips.get(status, u'')
self._status = status or ''
......@@ -355,7 +358,7 @@ class InputTypeBase(object):
context = self._get_render_context()
html = self.capa_system.render_template(self.template, context)
html = self.capa_system.render_template(self.template, context).strip()
try:
output = etree.XML(html)
......@@ -426,6 +429,13 @@ class OptionInput(InputTypeBase):
return [Attribute('options', transform=cls.parse_options),
Attribute('inline', False)]
def _extra_context(self):
"""
Return extra context.
"""
_ = self.capa_system.i18n.ugettext
return {'default_option_text': _('Select an option')}
#-----------------------------------------------------------------------------
......
......@@ -7,7 +7,9 @@
%>
<form class="choicegroup capa_inputtype" id="inputtype_${id}">
<fieldset ${describedby}>
<legend id="${id}-legend" class="response-fieldset-legend field-group-hd">${response_data['label']}</legend>
% if response_data['label']:
<legend id="${id}-legend" class="response-fieldset-legend field-group-hd">${response_data['label']}</legend>
% endif
% for description_id, description_text in response_data['descriptions'].items():
<p class="question-description" id="${description_id}">${description_text}</p>
% endfor
......@@ -57,16 +59,8 @@
</fieldset>
<div class="indicator-container">
% if input_type == 'checkbox' or not value:
<span class="status ${status.classname if show_correctness != 'never' else 'unanswered'}" id="status_${id}" aria-describedby="inputtype_${id}" data-tooltip="${status.display_tooltip}">
<span class="sr">
%for choice_id, choice_label in choices:
% if choice_id in value:
${choice_label},
%endif
%endfor
-
${status.display_tooltip}
</span>
<span class="status ${status.classname if show_correctness != 'never' else 'unanswered'}" id="status_${id}" data-tooltip="${status.display_tooltip}">
<span class="sr">${status.display_tooltip}</span>
</span>
% endif
</div>
......
<%page expression_filter="h"/>
<%! from openedx.core.djangolib.markup import HTML %>
<% doinline = 'style="display:inline-block;vertical-align:top"' if inline else "" %>
<div id="formulaequationinput_${id}" class="inputtype formulaequationinput" ${doinline | n}>
<div id="formulaequationinput_${id}" class="inputtype formulaequationinput" ${doinline | n, decode.utf8}>
<div class="${status.classname}" id="status_${id}">
<label class="problem-group-label" for="input_${id}">${response_data['label']}</label>
% if response_data['label']:
<label class="problem-group-label" for="input_${id}">${response_data['label']}</label>
% endif
% for description_id, description_text in response_data['descriptions'].items():
<p class="question-description" id="${description_id}">${description_text}</p>
% endfor
<input type="text" name="input_${id}" id="input_${id}"
data-input-id="${id}" value="${value}"
${describedby| n}
${describedby | n, decode.utf8}
% if size:
size="${size}"
% endif
......@@ -17,9 +19,7 @@
<span class="trailing_text">${trailing_text}</span>
<span class="status" id="${id}_status" data-tooltip="${status.display_tooltip}">
<span class="sr">
${status.display_name}
</span>
<span class="sr">${status.display_tooltip}</span>
</span>
<p id="answer_${id}" class="answer"></p>
......
......@@ -2,16 +2,16 @@
<% doinline = "inline" if inline else "" %>
<form class="inputtype option-input ${doinline}">
<label class="problem-group-label" for="input_${id}">
${response_data['label']}
</label>
% if response_data['label']:
<label class="problem-group-label" for="input_${id}">${response_data['label']}</label>
% endif
% for description_id, description_text in response_data['descriptions'].items():
<p class="question-description" id="${description_id}">${description_text}</p>
% endfor
<select name="input_${id}" id="input_${id}" ${describedby}>
<option value="option_${id}_dummy_default"> </option>
<option value="option_${id}_dummy_default">${default_option_text}</option>
% for option_id, option_description in options:
<option value="${option_id}"
% if (option_id == value or option_id == answervariable):
......@@ -22,10 +22,8 @@
</select>
<div class="indicator-container">
<span class="status ${status.classname}"
id="status_${id}"
aria-describedby="input_${id}" data-tooltip="${status.display_tooltip}">
<span class="sr">${value|h} - ${status.display_tooltip}</span>
<span class="status ${status.classname}" id="status_${id}" data-tooltip="${status.display_tooltip}">
<span class="sr">${status.display_tooltip}</span>
</span>
</div>
<p class="answer" id="answer_${id}"></p>
......
<section class="solution-span">
<div class="solution-span">
<span id="solution_${id}"></span>
</section>
</div>
......@@ -16,11 +16,14 @@
<div style="display:none;" name="${hidden}" inputid="input_${id}" />
% endif
<label class="problem-group-label" for="input_${id}">${response_data['label']}</label>
% if response_data['label']:
<label class="problem-group-label" for="input_${id}">${response_data['label']}</label>
% endif
% for description_id, description_text in response_data['descriptions'].items():
<p class="question-description" id="${description_id}">${description_text}</p>
% endfor
<input type="text" name="input_${id}" id="input_${id}" ${describedby| n} value="${value}"
<input type="text" name="input_${id}" id="input_${id}" ${describedby | n, decode.utf8} value="${value}"
% if do_math:
class="math"
% endif
......@@ -33,16 +36,8 @@
/>
<span class="trailing_text">${trailing_text}</span>
<span class="status" aria-describedby="input_${id}" data-tooltip="${status.display_tooltip}">
<span class="sr">
%if value:
${value}
% else:
${response_data['label']}
%endif
-
${status.display_name}
</span>
<span class="status" data-tooltip="${status.display_tooltip}">
<span class="sr">${status.display_tooltip}</span>
</span>
<p id="answer_${id}" class="answer"></p>
......
......@@ -46,10 +46,9 @@ class CAPAProblemTest(unittest.TestCase):
)
self.assertEqual(len(problem.tree.xpath('//label')), 0)
def test_label_attribute_only(self):
def test_legacy_problem(self):
"""
Verify that label is extracted and <p> tag with question
text is removed when label attribute is set on inputtype.
Verify that legacy problem is handled correctly.
"""
question = "Once we become predictable, we become ______?"
xml = """
......@@ -67,15 +66,14 @@ class CAPAProblemTest(unittest.TestCase):
{
'1_2_1':
{
'label': question,
'label': '',
'descriptions': {}
}
}
)
self.assertEqual(
len(problem.tree.xpath('//p[text()="{}"]'.format(question))),
0
len(problem.tree.xpath("//*[normalize-space(text())='{}']".format(question))),
1
)
def test_neither_label_tag_nor_attribute(self):
......@@ -158,9 +156,9 @@ class CAPAProblemTest(unittest.TestCase):
}
)
def test_question_is_not_removed(self):
def test_non_accessible_inputtype(self):
"""
Verify that tag with question text is not removed when responsetype is not fully accessible.
Verify that tag with question text is not removed when inputtype is not fully accessible.
"""
question = "Click the country which is home to the Pyramids."
xml = """
......@@ -178,7 +176,7 @@ class CAPAProblemTest(unittest.TestCase):
{
'1_2_1':
{
'label': 'Click the country which is home to the Pyramids.',
'label': '',
'descriptions': {}
}
}
......@@ -261,22 +259,22 @@ class CAPAProblemTest(unittest.TestCase):
)
self.assertEqual(len(problem.tree.xpath('//label')), 0)
def test_label_attribute_mismatches_question_tag(self):
def test_question_title_not_removed_got_children(self):
"""
Verify that question text is extracted correctly when label attribtue value
mismatched with question tag value.
Verify that <p> question text before responsetype not deleted when
it contains other children and label is picked from label attribute of inputtype
This is the case when author updated the question <p> tag directly in XML but
didn't change the label attribute value. In this case we will consider the
first <p> tag before responsetype as question.
This is the case when author updated the <p> immediately before
responsetype to contain other elements. We do not want to delete information in that case.
"""
question = 'Select the correct synonym of paranoid?'
question = 'Is egg plant a fruit?'
xml = """
<problem>
<p>Choose wisely.</p>
<p>{}</p>
<p>Select the correct synonym of paranoid?</p>
<p><img src="" /></p>
<choiceresponse>
<checkboxgroup label="Is egg plant a fruit?">
<checkboxgroup label="{}">
<choice correct="true">over-suspicious</choice>
<choice correct="false">funny</choice>
</checkboxgroup>
......@@ -289,14 +287,14 @@ class CAPAProblemTest(unittest.TestCase):
{
'1_2_1':
{
'label': question,
'label': '',
'descriptions': {}
}
}
)
self.assertEqual(
len(problem.tree.xpath('//p[text()="{}"]'.format(question))),
0
len(problem.tree.xpath('//p/img')),
1
)
def test_multiple_inputtypes(self):
......@@ -339,18 +337,19 @@ class CAPAProblemTest(unittest.TestCase):
"""
Verify that HTML is correctly rendered when there is single inputtype.
"""
xml = """
question = 'Enter sum of 1+2'
xml = textwrap.dedent("""
<problem>
<choiceresponse>
<label>Select the correct synonym of paranoid?</label>
<description>Only the paranoid survive.</description>
<checkboxgroup>
<choice correct="true">over-suspicious</choice>
<choice correct="false">funny</choice>
</checkboxgroup>
</choiceresponse>
<customresponse cfn="test_sum" expect="3">
<script type="loncapa/python">
def test_sum(expect, ans):
return int(expect) == int(ans)
</script>
<label>{}</label>
<textline size="20" correct_answer="3" />
</customresponse>
</problem>
"""
""".format(question))
problem = new_loncapa_problem(xml, use_capa_render_template=True)
problem_html = etree.XML(problem.get_html())
......@@ -358,6 +357,10 @@ class CAPAProblemTest(unittest.TestCase):
multi_inputs_group = problem_html.xpath('//div[@class="multi-inputs-group"]')
self.assertEqual(len(multi_inputs_group), 0)
# verify that question is rendered only once
question = problem_html.xpath("//*[normalize-space(text())='{}']".format(question))
self.assertEqual(len(question), 1)
@ddt.ddt
class CAPAMultiInputProblemTest(unittest.TestCase):
......
......@@ -165,6 +165,40 @@ class TemplateTestCase(unittest.TestCase):
describedbys = xml.xpath(describedby_xpath)
self.assertFalse(describedbys)
def assert_status(self, status_div=False, status_class=False):
"""
Verify status information.
Arguments:
status_div (bool): check presence of status div
status_class (bool): check presence of status class
"""
cases = [
('correct', 'correct'),
('unsubmitted', 'unanswered'),
('incorrect', 'incorrect'),
('incomplete', 'incorrect')
]
for context_status, div_class in cases:
self.context['status'] = Status(context_status)
xml = self.render_to_xml(self.context)
# Expect that we get a <div> with correct class
if status_div:
xpath = "//div[normalize-space(@class)='%s']" % div_class
self.assert_has_xpath(xml, xpath, self.context)
# Expect that we get a <span> with class="status"
# (used to by CSS to draw the green check / red x)
self.assert_has_text(
xml,
"//span[@class=normalize-space('status {}')]/span[@class='sr']".format(
div_class if status_class else ''
),
self.context['status'].display_tooltip
)
class ChoiceGroupTemplateTest(TemplateTestCase):
"""
......@@ -407,6 +441,12 @@ class ChoiceGroupTemplateTest(TemplateTestCase):
self.assert_description(xpaths)
self.assert_describedby_attribute(xpaths)
def test_status(self):
"""
Verify status information.
"""
self.assert_status(status_class=True)
class TextlineTemplateTest(TemplateTestCase):
"""
......@@ -441,23 +481,10 @@ class TextlineTemplateTest(TemplateTestCase):
self.assert_has_xpath(xml, xpath, self.context)
def test_status(self):
cases = [('correct', 'correct', 'correct'),
('unsubmitted', 'unanswered', 'unanswered'),
('incorrect', 'incorrect', 'incorrect'),
('incomplete', 'incorrect', 'incomplete')]
for (context_status, div_class, status_mark) in cases:
self.context['status'] = Status(context_status)
xml = self.render_to_xml(self.context)
# Expect that we get a <div> with correct class
xpath = "//div[@class='%s ']" % div_class
self.assert_has_xpath(xml, xpath, self.context)
# Expect that we get a <span> with class="status"
# (used to by CSS to draw the green check / red x)
self.assert_has_text(xml, "//span[@class='status']/span[@class='sr']",
status_mark, exact=False)
"""
Verify status information.
"""
self.assert_status(status_div=True)
def test_label(self):
xml = self.render_to_xml(self.context)
......@@ -582,6 +609,12 @@ class FormulaEquationInputTemplateTest(TemplateTestCase):
self.assert_description(xpaths)
self.assert_describedby_attribute(xpaths)
def test_status(self):
"""
Verify status information.
"""
self.assert_status(status_div=True)
class AnnotationInputTemplateTest(TemplateTestCase):
"""
......@@ -767,6 +800,7 @@ class OptionInputTemplateTest(TemplateTestCase):
'options': [],
'status': Status('unsubmitted'),
'value': 0,
'default_option_text': 'Select an option',
'response_data': self.RESPONSE_DATA,
'describedby': self.DESCRIBEDBY,
}
......@@ -796,20 +830,10 @@ class OptionInputTemplateTest(TemplateTestCase):
self.assert_has_text(xml, xpath, 'Option 2')
def test_status(self):
# Test cases, where each tuple represents
# `(input_status, expected_css_class)`
test_cases = [('unsubmitted', 'status unanswered'),
('correct', 'status correct'),
('incorrect', 'status incorrect'),
('incomplete', 'status incorrect')]
for (input_status, expected_css_class) in test_cases:
self.context['status'] = Status(input_status)
xml = self.render_to_xml(self.context)
xpath = "//span[@class='{0}']".format(expected_css_class)
self.assert_has_xpath(xml, xpath, self.context)
"""
Verify status information.
"""
self.assert_status(status_class=True)
def test_label(self):
xml = self.render_to_xml(self.context)
......
......@@ -61,6 +61,7 @@ class OptionInputTest(unittest.TestCase):
'value': 'Down',
'id': 'sky_input',
'status': 'answered',
'default_option_text': 'Select an option',
'response_data': RESPONSE_DATA
}
option_input = lookup_tag('optioninput')(test_capa_system(), element, state)
......@@ -75,6 +76,7 @@ class OptionInputTest(unittest.TestCase):
'msg': '',
'inline': False,
'id': 'sky_input',
'default_option_text': 'Select an option',
'response_data': RESPONSE_DATA,
'describedby': DESCRIBEDBY
}
......
......@@ -23,7 +23,8 @@ var options = {
{pattern: 'common_static/coffee/src/ajax_prefix.js', included: true},
{pattern: 'common_static/common/js/vendor/underscore.js', included: true},
{pattern: 'common_static/common/js/vendor/backbone.js', included: true},
{pattern: 'common_static/js/vendor/CodeMirror/codemirror.js', included: true},
{pattern: 'common_static/js/vendor/codemirror-compressed.js', included: true},
{pattern: 'common_static/js/lib/pretty-print.js', included: true},
{pattern: 'common_static/js/vendor/draggabilly.js'},
{pattern: 'common_static/common/js/vendor/jquery.js', included: true},
{pattern: 'common_static/common/js/vendor/jquery-migrate.js', included: true},
......
......@@ -314,7 +314,7 @@ describe 'Problem', ->
html = '''
<div id="problem_sel">
<select>
<option value="val0"></option>
<option value="val0">Select an option</option>
<option value="val1">1</option>
<option value="val2">2</option>
</select>
......
......@@ -27,26 +27,38 @@ describe 'Markdown to xml extended hint dropdown', ->
""")
expect(data).toEqual("""
<problem>
<p>Translation between Dropdown and ________ is straightforward.</p>
<optionresponse>
<optioninput>
<option correct="True">Multiple Choice <optionhint label="Good Job">Yes, multiple choice is the right answer.</optionhint></option>
<option correct="False">Text Input <optionhint>No, text input problems don't present options.</optionhint></option>
<option correct="False">Numerical Input <optionhint>No, numerical input problems don't present options.</optionhint></option>
</optioninput>
</optionresponse>
<p>Clowns have funny _________ to make people laugh.</p>
<optionresponse>
<optioninput>
<option correct="False">dogs <optionhint label="NOPE">Not dogs, not cats, not toads</optionhint></option>
<option correct="True">FACES <optionhint>With lots of makeup, doncha know?</optionhint></option>
<option correct="False">money <optionhint>Clowns don't have any money, of course</optionhint></option>
<option correct="False">donkeys <optionhint>don't be an ass.</optionhint></option>
<option correct="False">-no hint-</option>
</optioninput>
</optionresponse>
<p>Translation between Dropdown and ________ is straightforward.</p>
<optionresponse>
<optioninput>
<option correct="True">Multiple Choice
<optionhint label="Good Job">Yes, multiple choice is the right answer.</optionhint>
</option>
<option correct="False">Text Input
<optionhint>No, text input problems don't present options.</optionhint>
</option>
<option correct="False">Numerical Input
<optionhint>No, numerical input problems don't present options.</optionhint>
</option>
</optioninput>
</optionresponse>
<p>Clowns have funny _________ to make people laugh.</p>
<optionresponse>
<optioninput>
<option correct="False">dogs
<optionhint label="NOPE">Not dogs, not cats, not toads</optionhint>
</option>
<option correct="True">FACES
<optionhint>With lots of makeup, doncha know?</optionhint>
</option>
<option correct="False">money
<optionhint>Clowns don't have any money, of course</optionhint>
</option>
<option correct="False">donkeys
<optionhint>don't be an ass.</optionhint>
</option>
<option correct="False">-no hint-</option>
</optioninput>
</optionresponse>
</problem>
""")
......
......@@ -498,7 +498,7 @@ class @Problem
@el.find("select").each (i, select_field) =>
selected_option = $(select_field).find("option:selected").text().trim()
if selected_option is ''
if selected_option is 'Select an option'
answered = false
if bind
$(select_field).on 'change', (e) =>
......
......@@ -531,7 +531,7 @@ class @MarkdownEditingDescriptor extends XModule.Descriptor
// replace code blocks
xml = xml.replace(/\[code\]\n?([^\]]*)\[\/?code\]/gmi, function(match, p1) {
var selectString = '<pre><code>\n' + p1 + '</code></pre>';
var selectString = '<pre><code>' + p1 + '</code></pre>';
return selectString;
});
......@@ -626,4 +626,6 @@ class @MarkdownEditingDescriptor extends XModule.Descriptor
# make all responsetypes descendants of a single problem element
## safe-lint: disable=javascript-concat-html
return '<problem>\n' + responseTypesXML.join('\n\n') + demandHints + '\n</problem>'
# format and return xml
finalXml = '<problem>' + responseTypesXML.join('\n\n') + demandHints + '</problem>'
return PrettyPrint.xml(finalXml);
......@@ -40,9 +40,9 @@ data: |
return test_add(10, ans)
</script>
<p>Enter two integers that sum to 10.</p>
<textline size="40" correct_answer="3"/><br/>
<textline size="40" correct_answer="7"/>
<label>Enter two integers that sum to 10.</label>
<textline size="40" correct_answer="3" label="Enter first number" /><br/>
<textline size="40" correct_answer="7" label="Enter second number" />
<solution>
<div class="detailed-solution">
<p>Explanation</p>
......@@ -63,9 +63,9 @@ data: |
return False
</script>
<p>Enter two integers that sum to 20.</p>
<textline size="40" correct_answer="11"/><br/>
<textline size="40" correct_answer="9"/>
<label>Enter two integers that sum to 20.</label>
<textline size="40" correct_answer="11" label="Enter first number" /><br/>
<textline size="40" correct_answer="9" label="Enter second number" />
<solution>
<div class="detailed-solution">
<p>Explanation</p>
......
......@@ -3,8 +3,7 @@ metadata:
display_name: Dropdown with Hints and Feedback
markdown: |
You can use this template as a guide to the simple editor markdown and OLX markup to use for dropdown with hints and feedback problems. Edit this component to replace this template with your own assessment.
>>Add the question text, or prompt, here. This text is required.||You can add an optional tip or note related to the prompt
like this. <<
>>Add the question text, or prompt, here. This text is required.||You can add an optional tip or note related to the prompt like this. <<
[[
an incorrect answer {{You can specify optional feedback like this, which appears after this answer is submitted.}}
(the correct answer)
......@@ -20,8 +19,7 @@ data: |
<optionresponse>
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for dropdown with hints and feedback problems. Edit this component to replace this template with your own assessment.</p>
<label>Add the question text, or prompt, here. This text is required.</label>
<description>You can add an optional tip or note related to the prompt
like this. </description>
<description>You can add an optional tip or note related to the prompt like this. </description>
<optioninput>
<option correct="False">an incorrect answer <optionhint>You can specify optional feedback like this, which appears after this answer is submitted.</optionhint></option>
<option correct="True">the correct answer</option>
......
......@@ -35,7 +35,7 @@ data: |
hint = "&lt;font color='blue'&gt;Hint: {0}&lt;/font&gt;".format(hint)
new_cmap.set_hint_and_mode(aid,hint,'always')
</script>
<p>What is the best programming language that exists today? You may enter your answer in upper or lower case, with or without quotes.</p>
<label>What is the best programming language that exists today? You may enter your answer in upper or lower case, with or without quotes.</label>
<textline correct_answer="python"/>
<hintgroup hintfn="hint_fn"/>
</customresponse>
......
......@@ -3,12 +3,9 @@ metadata:
display_name: Text Input with Hints and Feedback
markdown: |
You can use this template as a guide to the simple editor markdown and OLX markup to use for text
input with hints and feedback problems. Edit this component to replace this template with your
own assessment.
You can use this template as a guide to the simple editor markdown and OLX markup to use for text input with hints and feedback problems. Edit this component to replace this template with your own assessment.
>>Add the question text, or prompt, here. This text is required.||You can add an optional tip or
note related to the prompt like this. <<
>>Add the question text, or prompt, here. This text is required.||You can add an optional tip or note related to the prompt like this. <<
= the correct answer {{You can specify optional feedback like this, which appears after this answer is submitted.}}
or= optional acceptable variant of the correct answer
......@@ -21,8 +18,7 @@ hinted: true
data: |
<problem>
<stringresponse answer="the correct answer" type="ci">
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for text input with</p>
<p>hints and feedback problems. Edit this component to replace this template with your own assessment.</p>
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for text input with hints and feedback problems. Edit this component to replace this template with your own assessment.</p>
<label>Add the question text, or prompt, here. This text is required.</label>
<description>You can add an optional tip or note related to the prompt like this.</description>
<correcthint>You can specify optional feedback like this, which appears after this answer is submitted.</correcthint>
......
/**
* pretty-data - nodejs plugin to pretty-print or minify data in XML, JSON and CSS formats.
*
* Version - 0.40.0
* Copyright (c) 2012 Vadim Kiryukhin
* vkiryukhin @ gmail.com
* http://www.eslinstructor.net/pretty-data/
*
*
* Code extracted for xml formatting only
*/
/* eslint-disable */
(function (root, factory){
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], function (){
return (root.PrettyPrint = factory());
});
} else {
// Browser globals
root.PrettyPrint = factory();
}
}(this, function () {
function PrettyPrint(){
var maxdeep = 100, // nesting level
ix = 0;
this.shift = ['\n']; // array of shifts
this.step = ' '; // 2 spaces
// initialize array with shifts //
for (ix = 0; ix < maxdeep; ix++) {
this.shift.push(this.shift[ix] + this.step);
}
}
PrettyPrint.prototype.xml = function (text) {
var ar = text.replace(/>\s{0,}</g, "><")
.replace(/</g, "~::~<")
.replace(/xmlns\:/g, "~::~xmlns:")
.replace(/xmlns\=/g, "~::~xmlns=")
.split('~::~'),
len = ar.length,
inComment = false,
deep = 0,
str = '',
ix = 0;
for (ix = 0; ix < len; ix++) {
// start comment or <![CDATA[...]]> or <!DOCTYPE //
if (ar[ix].search(/<!/) > -1) {
str += this.shift[deep] + ar[ix];
inComment = true;
// end comment or <![CDATA[...]]> //
if (ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1) {
inComment = false;
}
} else
// end comment or <![CDATA[...]]> //
if (ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
str += ar[ix];
inComment = false;
} else
// <elm></elm> //
if (/^<\w/.exec(ar[ix - 1]) && /^<\/\w/.exec(ar[ix]) &&
/^<[\w:\-\.\,]+/.exec(ar[ix - 1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/', '')) {
str += ar[ix];
if (!inComment) deep--;
} else
// <elm> //
if (ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1) {
str = !inComment ? str += this.shift[deep++] + ar[ix] : str += ar[ix];
} else
// <elm>...</elm> //
if (ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
str = !inComment ? str += this.shift[deep] + ar[ix] : str += ar[ix];
} else
// </elm> //
if (ar[ix].search(/<\//) > -1) {
str = !inComment ? str += this.shift[--deep] + ar[ix] : str += ar[ix];
} else
// <elm/> //
if (ar[ix].search(/\/>/) > -1) {
str = !inComment ? str += this.shift[deep] + ar[ix] : str += ar[ix];
} else
// <? xml ... ?> //
if (ar[ix].search(/<\?/) > -1) {
str += this.shift[deep] + ar[ix];
} else
// xmlns //
if (ar[ix].search(/xmlns\:/) > -1 || ar[ix].search(/xmlns\=/) > -1) {
str += this.shift[deep] + ar[ix];
}
else {
str += ar[ix];
}
}
return (str[0] == '\n') ? str.slice(1) : str;
};
return new PrettyPrint();
}));
describe('XML Formatting Lib', function() {
'use strict';
it('correctly format the xml', function() {
var rawXml = '<breakfast><food><name>Belgian Waffles</name><price>$5.95</price></food></breakfast>',
expectedXml = '<breakfast>\n <food>\n <name>Belgian Waffles</name>' +
'\n <price>$5.95</price>\n </food>\n</breakfast>';
expect(window.PrettyPrint.xml(rawXml)).toEqual(expectedXml);
});
it('correctly handles the whitespaces and newlines', function() {
var rawXml = '<breakfast> <food> <name>Belgian Waffles</name>' +
'\n\n\n<price>$5.95</price></food> </breakfast>',
expectedXml = '<breakfast>\n <food>\n <name>Belgian Waffles</name>' +
'\n <price>$5.95</price>\n </food>\n</breakfast>';
expect(window.PrettyPrint.xml(rawXml)).toEqual(expectedXml);
});
});
......@@ -28,6 +28,7 @@ var options = {
{pattern: 'js/vendor/URI.min.js', included: true},
{pattern: 'js/test/add_ajax_prefix.js', included: true},
{pattern: 'js/test/i18n.js', included: true},
{pattern: 'js/lib/pretty-print.js', included: true},
{pattern: 'common/js/vendor/underscore.js', included: true},
{pattern: 'common/js/vendor/underscore.string.js', included: true},
......
......@@ -218,11 +218,11 @@ class CertificateProgressPageTest(UniqueCourseTest):
self.course_nav.q(css='select option[value="{}"]'.format('blue')).first.click()
# Select correct radio button for the answer
self.course_nav.q(css='fieldset div.field:nth-child(4) input').nth(0).click()
self.course_nav.q(css='fieldset div.field:nth-child(3) input').nth(0).click()
# Select correct radio buttons for the answer
self.course_nav.q(css='fieldset div.field:nth-child(2) input').nth(1).click()
self.course_nav.q(css='fieldset div.field:nth-child(4) input').nth(1).click()
self.course_nav.q(css='fieldset div.field:nth-child(1) input').nth(1).click()
self.course_nav.q(css='fieldset div.field:nth-child(3) input').nth(1).click()
# Submit the answer
self.course_nav.q(css='button.check.Check').click()
......
......@@ -31,7 +31,7 @@ var options = {
{pattern: 'common/js/xblock/*.js', included: true},
{pattern: 'xmodule_js/common_static/js/src/logger.js', included: true},
{pattern: 'xmodule_js/common_static/js/test/i18n.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/codemirror-compressed.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.cookie.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/flot/jquery.flot.js', included: true},
{pattern: 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents.js', included: true},
......
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