Skip to content
Snippets Groups Projects
Commit feef179e authored by Calen Pennington's avatar Calen Pennington
Browse files

Merge remote-tracking branch 'origin/master' into cpennington/cms-xml-processing

Conflicts:
	cms/envs/common.py
parents 6fdf44fe 19044abe
No related merge requests found
Showing
with 129 additions and 85 deletions
......@@ -157,8 +157,8 @@ PIPELINE_CSS = {
PIPELINE_ALWAYS_RECOMPILE = ['sass/base-style.scss']
from x_module import XModuleDescriptor
from raw_module import RawDescriptor
from xmodule.x_module import XModuleDescriptor
from xmodule.raw_module import RawDescriptor
js_file_dir = PROJECT_ROOT / "static" / "coffee" / "module"
try:
os.makedirs(js_file_dir)
......
<section id="textinput_${id}" class="textinput">
% if state == 'unsubmitted':
<div class="unanswered" id="status_${id}">
% elif state == 'correct':
<div class="correct" id="status_${id}">
% elif state == 'incorrect':
<div class="incorrect" id="status_${id}">
% elif state == 'incomplete':
<div class="incorrect" id="status_${id}">
% endif
<input type="text" name="input_${id}" id="input_${id}" value="${value}"
% if size:
size="${size}"
% endif
/>
<span id="answer_${id}"></span>
<p class="status">
% if state == 'unsubmitted':
unanswered
% elif state == 'correct':
correct
% elif state == 'incorrect':
incorrect
% elif state == 'incomplete':
incomplete
% endif
</p>
<p id="answer_${id}" class="answer"></p>
% if state == 'unsubmitted':
<span class="unanswered" style="display:inline-block;" id="status_${id}"></span>
% elif state == 'correct':
<span class="correct" id="status_${id}"></span>
% elif state == 'incorrect':
<span class="incorrect" id="status_${id}"></span>
% elif state == 'incomplete':
<span class="incorrect" id="status_${id}"></span>
% endif
% if msg:
<span class="message">${msg|n}</span>
% endif
</div>
</section>
......@@ -2,34 +2,36 @@
### version of textline.html which does dynammic math
###
<section class="text-input-dynamath">
<table style="display:inline; vertical-align:middle;">
<tr>
<td>
<input type="text" name="input_${id}" id="input_${id}" value="${value}" class="math" size="${size if size else ''}" />
</td>
<td>
<span id="answer_${id}"></span>
% if state == 'unsubmitted':
<div class="unanswered" id="status_${id}">
% elif state == 'correct':
<div class="correct" id="status_${id}">
% elif state == 'incorrect':
<div class="incorrect" id="status_${id}">
% elif state == 'incomplete':
<div class="incorrect" id="status_${id}">
% endif
<input type="text" name="input_${id}" id="input_${id}" value="${value}" class="math" size="${size if size else ''}" />
<p class="status">
% if state == 'unsubmitted':
<span class="unanswered" style="display:inline-block;" id="status_${id}"></span>
unanswered
% elif state == 'correct':
<span class="correct" id="status_${id}"></span>
correct
% elif state == 'incorrect':
<span class="incorrect" id="status_${id}"></span>
incorrect
% elif state == 'incomplete':
<span class="incorrect" id="status_${id}"></span>
incomplete
% endif
</td>
</tr>
<tr>
<td>
<span id="display_${id}">`{::}`</span>
</td>
<td>
</p>
<p id="answer_${id}" class="answer"></p>
<div id="display_${id}" class="equation">`{::}`</div>
</div>
<textarea style="display:none" id="input_${id}_dynamath" name="input_${id}_dynamath"> </textarea>
</td>
</tr>
</table>
% if msg:
<span class="message">${msg|n}</span>
% endif
......
......@@ -14,7 +14,7 @@
import logging
log = logging.getLogger("mitx.common.lib.mitxmako")
log = logging.getLogger("mitx." + __name__)
from django.template import Context
from django.http import HttpResponse
......
......@@ -223,7 +223,7 @@ def get_module(tree, module, id_tag, module_id, sections_dirname, options):
result_set = tree.xpath(xpath_search)
if len(result_set) < 1:
# Not found in main tree. Let's look in the section files.
section_list = (s[:-4] for s in os.listdir(sections_dirname) if s[-4:]=='.xml')
section_list = (s[:-4] for s in os.listdir(sections_dirname) if s.endswith('.xml'))
for section in section_list:
try:
s = get_section(section, options, sections_dirname)
......
......@@ -176,11 +176,13 @@ def get_score(user, problem, cache, coursename=None):
## HACK 2: Backwards-compatibility: This should be written when a grade is saved, and removed from the system
# TODO: These are no longer correct params for I4xSystem -- figure out what this code
# does, clean it up.
from module_render import I4xSystem
system = I4xSystem(None, None, None, coursename=coursename)
total=float(xmodule.capa_module.Module(system, etree.tostring(problem), "id").max_score())
response.max_grade = total
response.save()
# from module_render import I4xSystem
# system = I4xSystem(None, None, None, coursename=coursename)
# total=float(xmodule.capa_module.Module(system, etree.tostring(problem), "id").max_score())
# response.max_grade = total
# response.save()
total = 1
# For a temporary fix, we just assume a problem is worth 1 point if we haven't seen it before. This is totally incorrect
#Now we re-weight the problem, if specified
weight = problem.get("weight", None)
......
......@@ -15,7 +15,7 @@ middleware.MakoMiddleware()
def check_names(user, course):
'''
Complain if any problems have alphanumeric names.
Complain if any problems have non alphanumeric names.
TODO (vshnayder): there are some in 6.002x that don't. Is that actually a problem?
'''
all_ok = True
......
......@@ -20,10 +20,12 @@ jasmine.stubRequests = ->
settings.success data: jasmine.stubbedMetadata[match[1]]
else if match = settings.url.match /static\/subs\/(.+)\.srt\.sjson/
settings.success jasmine.stubbedCaption
else if settings.url.match /modx\/problem\/.+\/problem_get$/
settings.success html: readFixtures('problem_content.html')
else if settings.url == '/calculate' ||
settings.url == '/6002x/modx/sequence/1/goto_position' ||
settings.url.match(/event$/) ||
settings.url.match(/6002x\/modx\/problem\/.+\/problem_(check|reset|show|save)$/)
settings.url.match(/modx\/problem\/.+\/problem_(check|reset|show|save)$/)
# do nothing
else
throw "External request attempted for #{settings.url}, which is not defined."
......
......@@ -13,6 +13,7 @@ describe 'Problem', ->
spyOn($.fn, 'load').andCallFake (url, callback) ->
$(@).html readFixtures('problem_content.html')
callback()
jasmine.stubRequests()
describe 'constructor', ->
beforeEach ->
......@@ -21,12 +22,6 @@ describe 'Problem', ->
it 'set the element', ->
expect(@problem.element).toBe '#problem_1'
it 'set the content url', ->
expect(@problem.content_url).toEqual '/problem/url/problem_get?id=1'
it 'render the content', ->
expect($.fn.load).toHaveBeenCalledWith @problem.content_url, @problem.bind
describe 'bind', ->
beforeEach ->
spyOn window, 'update_schematics'
......@@ -57,8 +52,11 @@ describe 'Problem', ->
it 'bind the math input', ->
expect($('input.math')).toHandleWith 'keyup', @problem.refreshMath
it 'display the math input', ->
expect(@stubbedJax.root.toMathML).toHaveBeenCalled()
it 'replace math content on the page', ->
expect(MathJax.Hub.Queue.mostRecentCall.args).toEqual [
['Text', @stubbedJax, ''],
[@problem.updateMathML, @stubbedJax, $('#input_example_1').get(0)]
]
describe 'render', ->
beforeEach ->
......@@ -77,12 +75,19 @@ describe 'Problem', ->
expect(@problem.bind).toHaveBeenCalled()
describe 'with no content given', ->
beforeEach ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) ->
callback html: "Hello World"
@problem.render()
it 'load the content via ajax', ->
expect($.fn.load).toHaveBeenCalledWith @problem.content_url, @bind
expect(@problem.element.html()).toEqual 'Hello World'
it 're-bind the content', ->
expect(@problem.bind).toHaveBeenCalled()
describe 'check', ->
beforeEach ->
jasmine.stubRequests()
@problem = new Problem 1, '/problem/url/'
@problem.answers = 'foo=1&bar=2'
......@@ -116,7 +121,6 @@ describe 'Problem', ->
describe 'reset', ->
beforeEach ->
jasmine.stubRequests()
@problem = new Problem 1, '/problem/url/'
it 'log the problem_reset event', ->
......@@ -130,13 +134,13 @@ describe 'Problem', ->
expect($.postWithPrefix).toHaveBeenCalledWith '/modx/problem/1/problem_reset', { id: 1 }, jasmine.any(Function)
it 'render the returned content', ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) -> callback("Reset!")
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
callback html: "Reset!"
@problem.reset()
expect(@problem.element.html()).toEqual 'Reset!'
describe 'show', ->
beforeEach ->
jasmine.stubRequests()
@problem = new Problem 1, '/problem/url/'
@problem.element.prepend '<div id="answer_1_1" /><div id="answer_1_2" />'
......@@ -154,18 +158,19 @@ describe 'Problem', ->
expect($.postWithPrefix).toHaveBeenCalledWith '/modx/problem/1/problem_show', jasmine.any(Function)
it 'show the answers', ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback('1_1': 'One', '1_2': 'Two')
spyOn($, 'postWithPrefix').andCallFake (url, callback) ->
callback answers: '1_1': 'One', '1_2': 'Two'
@problem.show()
expect($('#answer_1_1')).toHaveHtml 'One'
expect($('#answer_1_2')).toHaveHtml 'Two'
it 'toggle the show answer button', ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback({})
spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback(answers: {})
@problem.show()
expect($('.show')).toHaveValue 'Hide Answer'
it 'add the showed class to element', ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback({})
spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback(answers: {})
@problem.show()
expect(@problem.element).toHaveClass 'showed'
......@@ -179,7 +184,8 @@ describe 'Problem', ->
'''
it 'set the correct_answer attribute on the choice', ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback('1_1': [2, 3])
spyOn($, 'postWithPrefix').andCallFake (url, callback) ->
callback answers: '1_1': [2, 3]
@problem.show()
expect($('label[for="input_1_1_1"]')).not.toHaveAttr 'correct_answer', 'true'
expect($('label[for="input_1_1_2"]')).toHaveAttr 'correct_answer', 'true'
......@@ -214,7 +220,6 @@ describe 'Problem', ->
describe 'save', ->
beforeEach ->
jasmine.stubRequests()
@problem = new Problem 1, '/problem/url/'
@problem.answers = 'foo=1&bar=2'
......@@ -236,23 +241,29 @@ describe 'Problem', ->
describe 'refreshMath', ->
beforeEach ->
@problem = new Problem 1, '/problem/url/'
@stubbedJax.root.toMathML.andReturn '<MathML>'
$('#input_example_1').val 'E=mc^2'
@problem.refreshMath target: $('#input_example_1').get(0)
it 'should queue the conversion and MathML element update', ->
expect(MathJax.Hub.Queue).toHaveBeenCalledWith ['Text', @stubbedJax, 'E=mc^2'],
[@problem.updateMathML, @stubbedJax, $('#input_example_1').get(0)]
describe 'updateMathML', ->
beforeEach ->
@problem = new Problem 1, '/problem/url/'
@stubbedJax.root.toMathML.andReturn '<MathML>'
describe 'when there is no exception', ->
beforeEach ->
@problem.refreshMath target: $('#input_example_1').get(0)
it 'should convert and display the MathML object', ->
expect(MathJax.Hub.Queue).toHaveBeenCalledWith ['Text', @stubbedJax, 'E=mc^2']
@problem.updateMathML @stubbedJax, $('#input_example_1').get(0)
it 'should display debug output in hidden div', ->
it 'convert jax to MathML', ->
expect($('#input_example_1_dynamath')).toHaveValue '<MathML>'
describe 'when there is an exception', ->
beforeEach ->
@stubbedJax.root.toMathML.andThrow {restart: true}
@problem.refreshMath target: $('#input_example_1').get(0)
@problem.updateMathML @stubbedJax, $('#input_example_1').get(0)
it 'should queue up the exception', ->
expect(MathJax.Callback.After).toHaveBeenCalledWith [@problem.refreshMath, @stubbedJax], true
......
......@@ -35,6 +35,9 @@ describe 'VideoCaption', ->
it 'bind player resize event', ->
expect($(@player)).toHandleWith 'resize', @caption.onWindowResize
it 'bind player seek event', ->
expect($(@player)).toHandleWith 'seek', @caption.onUpdatePlayTime
it 'bind player updatePlayTime event', ->
expect($(@player)).toHandleWith 'updatePlayTime', @caption.onUpdatePlayTime
......
class @Problem
constructor: (@id, url) ->
@element = $("#problem_#{id}")
@content_url = "#{url}problem_get?id=#{@id}"
@render()
$: (selector) ->
......@@ -17,7 +16,7 @@ class @Problem
@$('section.action input.save').click @save
@$('input.math').keyup(@refreshMath).each(@refreshMath)
update_progress: (response) =>
updateProgress: (response) =>
if response.progress_changed
@element.attr progress: response.progress_status
@element.trigger('progressChanged')
......@@ -27,10 +26,9 @@ class @Problem
@element.html(content)
@bind()
else
$.postWithPrefix "/modx/problem/#{@id}/problem_get", '', (response) =>
$.postWithPrefix "/modx/problem/#{@id}/problem_get", (response) =>
@element.html(response.html)
@bind()
check: =>
Logger.log 'problem_check', @answers
......@@ -38,7 +36,7 @@ class @Problem
switch response.success
when 'incorrect', 'correct'
@render(response.contents)
@update_progress response
@updateProgress response
else
alert(response.success)
......@@ -46,7 +44,7 @@ class @Problem
Logger.log 'problem_reset', @answers
$.postWithPrefix "/modx/problem/#{@id}/problem_reset", id: @id, (response) =>
@render(response.html)
@update_progress response
@updateProgress response
show: =>
if !@element.hasClass 'showed'
......@@ -62,7 +60,7 @@ class @Problem
MathJax.Hub.Queue ["Typeset", MathJax.Hub]
@$('.show').val 'Hide Answer'
@element.addClass 'showed'
@update_progress response
@updateProgress response
else
@$('[id^=answer_], [id^=solution_]').text ''
@$('[correct_answer]').attr correct_answer: null
......@@ -74,21 +72,22 @@ class @Problem
$.postWithPrefix "/modx/problem/#{@id}/problem_save", @answers, (response) =>
if response.success
alert 'Saved'
@update_progress response
@updateProgress response
refreshMath: (event, element) =>
element = event.target unless element
target = "display_#{element.id.replace(/^input_/, '')}"
if jax = MathJax.Hub.getAllJax(target)[0]
MathJax.Hub.Queue ['Text', jax, $(element).val()]
MathJax.Hub.Queue ['Text', jax, $(element).val()],
[@updateMathML, jax, element]
try
output = jax.root.toMathML ''
$("##{element.id}_dynamath").val(output)
catch exception
throw exception unless exception.restart
MathJax.Callback.After [@refreshMath, jax], exception.restart
updateMathML: (jax, element) =>
try
$("##{element.id}_dynamath").val(jax.root.toMathML '')
catch exception
throw exception unless exception.restart
MathJax.Callback.After [@refreshMath, jax], exception.restart
refreshAnswers: =>
@$('input.schematic').each (index, element) ->
......
......@@ -10,6 +10,7 @@ class @VideoCaption
$(window).bind('resize', @onWindowResize)
$(@player).bind('resize', @onWindowResize)
$(@player).bind('updatePlayTime', @onUpdatePlayTime)
$(@player).bind('seek', @onUpdatePlayTime)
$(@player).bind('play', @onPlay)
@$('.hide-subtitles').click @toggle
@$('.subtitles').mouseenter(@onMouseEnter).mouseleave(@onMouseLeave)
......
lms/static/images/sequence-nav/status/check.png

211 B

lms/static/images/sequence-nav/status/dash.png

86 B

lms/static/images/sequence-nav/status/not-started.png

124 B

lms/static/images/sequence-nav/status/wrong.png

178 B

......@@ -23,3 +23,7 @@ The dev server will automatically compile sass files that have changed. Simply s
the server using:
$ rake runserver
To run it along side of development:
$ sass --watch lms/static/sass:lms/static/sass -r ./lms/static/sass/bourbon/lib/bourbon.rb
......@@ -62,6 +62,8 @@ div.book-wrapper {
@extend .clearfix;
li {
background-color: darken($cream, 4%);
&.last {
display: block;
float: left;
......@@ -77,6 +79,10 @@ div.book-wrapper {
display: block;
float: right;
}
&:hover {
background: none;
}
}
}
......
......@@ -7,7 +7,7 @@
@import "plugins/jquery-ui-1.8.16.custom", "plugins/jquery.qtip.min";
// pages
@import "courseware/courseware", "courseware/sidebar", "courseware/video", "courseware/sequence-nav", "courseware/amplifier";
@import "courseware/courseware", "courseware/sidebar", "courseware/video", "courseware/sequence-nav", "courseware/amplifier", "courseware/problems";
@import "textbook";
@import "info";
@import "profile";
......
......@@ -205,7 +205,7 @@ h1.top-header {
border-top: 1px solid #fff;
// @include box-shadow(inset 0 1px 0 #fff, inset 1px 0 0 #fff);
font-size: 12px;
height:46px;
// height:46px;
line-height: 46px;
margin: (-$body-line-height) (-$body-line-height) $body-line-height;
text-shadow: 0 1px 0 #fff;
......@@ -224,7 +224,7 @@ h1.top-header {
}
&.block-link {
background: darken($cream, 5%);
// background: darken($cream, 5%);
border-left: 1px solid darken($cream, 20%);
@include box-shadow(inset 1px 0 0 lighten($cream, 5%));
display: block;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment