Merge pull request #91 from MITx/ps-dynamath
Refactor and test Dynamath Code (tested, works; one more changeset coming, to add msg back into textinput_dynamath)
This commit is contained in:
@@ -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">
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
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_/, '')}"
|
||||
|
||||
if 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>
|
||||
|
||||
Reference in New Issue
Block a user