Commit 03d976be by ichuang

Merge branch 'ps-dynamath' of github.com:MITx/mitx into dogfood-xmodule

parents 9d0dfd2f f9ad0bd9
......@@ -2,49 +2,32 @@
### 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}"
% if size:
size="${size}"
% endif
onkeyup="DoUpdateMath('${id}')"
/>
</td><td>
<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>
<span id="answer_${id}"></span>
% 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
</td></tr><tr><td>
<span id="display_${id}">`{::}`</span>
</td><td>
<textarea style="display:none" id="input_${id}_dynamath" name="input_${id}_dynamath"> </textarea>
</td></tr>
</table>
##
## javascript for dynamic math: add this math element to the MathJax rendering queue
## also adds to global jaxset js array
##
<script type="text/javascript">
MathJax.Hub.queue.Push(function () {
math = MathJax.Hub.getAllJax("display_${id}")[0];
if (math){
jaxset["${id}"] = math;
math.Text(document.getElementById("input_${id}").value);
// UpdateMathML(math,"${id}");
}
});
</script>
% if msg:
<br/>
<span class="debug">${msg|n}</span>
% endif
% 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
</td>
</tr>
<tr>
<td>
<span id="display_${id}">`{::}`</span>
</td>
<td>
<textarea style="display:none" id="input_${id}_dynamath" name="input_${id}_dynamath"> </textarea>
</td>
</tr>
</table>
</section>
......@@ -6,6 +6,10 @@
<section class="action">
<input type="hidden" name="problem_id" value="1">
<input type="text" name="input_example_1" id="input_example_1" value="" class="math" />
<span id="display_example_1"></span>
<span id="input_example_1_dynamath"></span>
<input class="check" type="button" value="Check">
<input class="reset" type="button" value="Reset">
<input class="save" type="button" value="Save">
......
describe 'Problem', ->
beforeEach ->
# Stub MathJax
window.MathJax = { Hub: { Queue: -> } }
window.MathJax =
Hub: jasmine.createSpyObj('MathJax.Hub', ['getAllJax', 'Queue'])
Callback: jasmine.createSpyObj('MathJax.Callback', ['After'])
@stubbedJax = root: jasmine.createSpyObj('jax.root', ['toMathML'])
MathJax.Hub.getAllJax.andReturn [@stubbedJax]
window.update_schematics = ->
loadFixtures 'problem.html'
......@@ -25,8 +29,8 @@ describe 'Problem', ->
describe 'bind', ->
beforeEach ->
spyOn MathJax.Hub, 'Queue'
spyOn window, 'update_schematics'
MathJax.Hub.getAllJax.andReturn [@stubbedJax]
@problem = new Problem 1, '/problem/url/'
it 'set mathjax typeset', ->
......@@ -50,6 +54,12 @@ describe 'Problem', ->
it 'bind the save button', ->
expect($('section.action input.save')).toHandleWith 'click', @problem.save
it 'bind the math input', ->
expect($('input.math')).toHandleWith 'keyup', @problem.refreshMath
it 'display the math input', ->
expect(@stubbedJax.root.toMathML).toHaveBeenCalled()
describe 'render', ->
beforeEach ->
@problem = new Problem 1, '/problem/url/'
......@@ -223,6 +233,30 @@ describe 'Problem', ->
@problem.save()
expect(window.alert).toHaveBeenCalledWith 'Saved'
describe 'refreshMath', ->
beforeEach ->
@problem = new Problem 1, '/problem/url/'
@stubbedJax.root.toMathML.andReturn '<MathML>'
$('#input_example_1').val 'E=mc^2'
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']
it 'should display debug output in hidden div', ->
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)
it 'should queue up the exception', ->
expect(MathJax.Callback.After).toHaveBeenCalledWith [@problem.refreshMath, @stubbedJax], true
describe 'refreshAnswers', ->
beforeEach ->
@problem = new Problem 1, '/problem/url/'
......
......@@ -15,6 +15,7 @@ class @Problem
@$('section.action input.reset').click @reset
@$('section.action input.show').click @show
@$('section.action input.save').click @save
@$('input.math').keyup(@refreshMath).each(@refreshMath)
render: (content) ->
if content
......@@ -62,6 +63,20 @@ class @Problem
if response.success
alert 'Saved'
refreshMath: (event, element) =>
element = event.target unless element
target = "display_#{element.id.replace(/^input_/, '')}"
jax = MathJax.Hub.getAllJax(target)[0]
MathJax.Hub.Queue ['Text', jax, $(element).val()]
try
output = jax.root.toMathML ''
$("##{element.id}_dynamath").val(output)
catch exception
throw exception unless exception.restart
MathJax.Callback.After [@refreshMath, jax], exception.restart
refreshAnswers: =>
@$('input.schematic').each (index, element) ->
element.schematic.update_value()
......
......@@ -5,82 +5,22 @@
##
## This enables ASCIIMathJAX, and is used by js_textbox
<script type="text/x-mathjax-config">
// (function () {
var QUEUE = MathJax.Hub.queue; // shorthand for the queue
var math = null;
var jaxset = {}; // associative array of the element jaxs for the math output.
var mmlset = {}; // associative array of mathml from each jax
// constructs mathML of the specified jax element
function toMathML(jax,callback) {
var mml;
try {
mml = jax.root.toMathML("");
} catch(err) {
if (!err.restart) {throw err} // an actual error
return MathJax.Callback.After([toMathML,jax,callback],err.restart);
}
MathJax.Callback(callback)(mml);
}
// function to queue in MathJax to get put the MathML expression in in the right document element
function UpdateMathML(jax,id) {
toMathML(jax,function (mml) {
// document.getElementById(id+'_dynamath').value=math.originalText+ "\n\n=>\n\n"+ mml;
delem = document.getElementById("input_" + id + "_dynamath");
if (delem) { delem.value=mml; };
mmlset[id] = mml;
})
}
MathJax.Hub.Config({
tex2jax: {
inlineMath: [
["\\(","\\)"],
['[mathjaxinline]','[/mathjaxinline]']
],
displayMath: [
["\\[","\\]"],
['[mathjax]','[/mathjax]']
]
}
});
//
// The onchange event handler that typesets the
// math entered by the user
//
window.UpdateMath = function (Am,id) {
QUEUE.Push(["Text",jaxset[id],Am]);
QUEUE.Push(UpdateMathML(jaxset[id],id));
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [
["\\(","\\)"],
['[mathjaxinline]','[/mathjaxinline]']
],
displayMath: [
["\\[","\\]"],
['[mathjax]','[/mathjax]']
]
}
});
</script>
// })();
function DoUpdateMath(inputId) {
var str = document.getElementById("input_"+inputId).value;
// make sure the input field is in the jaxset
if ($.inArray(inputId,jaxset) == -1){
//alert('missing '+inputId);
if (document.getElementById("display_" + inputId)){
MathJax.Hub.queue.Push(function () {
math = MathJax.Hub.getAllJax("display_" + inputId)[0];
if (math){
jaxset[inputId] = math;
}
});
};
}
UpdateMath(str,inputId)
}
</script>
<!-- This must appear after all mathjax-config blocks, so it is after the imports from the other templates.
It can't be run through static.url because MathJax uses crazy url introspection to do lazy loading of
MathJax extension libraries -->
<script type="text/javascript" src="/static/js/mathjax-MathJax-c9db6ac/MathJax.js?config=TeX-MML-AM_HTMLorMML-full"></script>
<!-- This must appear after all mathjax-config blocks, so it is after the imports from the other templates.
It can't be run through static.url because MathJax uses crazy url introspection to do lazy loading of
MathJax extension libraries -->
<script type="text/javascript" src="/static/js/mathjax-MathJax-c9db6ac/MathJax.js?config=TeX-MML-AM_HTMLorMML-full"></script>
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