Commit e312344d by Peter Baratta

Fix initial loading bug.

Change the `MathJax.Hub.Queue(initializeRequest)` to a simpler function call
(`initializeRequest.call(this)`). This was failing to give a proper context
to initializeRequest, and `this.value` was turning up as `undefined`.

Also add a fallback if we need to display some code before MathJax finishes
its original typesetting.

I was stubbing out `Queue` in my specs, so the tests had to be changed around
a little.
parent a7568fbf
...@@ -77,37 +77,33 @@ describe("Formula Equation Preview", function () { ...@@ -77,37 +77,33 @@ describe("Formula Equation Preview", function () {
}); });
describe('Ajax requests', function () { describe('Ajax requests', function () {
it('has an initial request with the correct parameters', function () { beforeEach(function () {
// This is common to all tests on ajax requests.
formulaEquationPreview.enable(); formulaEquationPreview.enable();
expect(MathJax.Hub.Queue).toHaveBeenCalled();
// Do what Queue would've done--call the function.
var args = MathJax.Hub.Queue.mostRecentCall.args;
args[1].call(args[0]);
// This part may be asynchronous, so wait. // This part may be asynchronous, so wait.
waitsFor(function () { waitsFor(function () {
return Problem.inputAjax.wasCalled; return Problem.inputAjax.wasCalled;
}, "AJAX never called initially", 1000); }, "AJAX never called initially", 1000);
});
runs(function () { it('has an initial request with the correct parameters', function () {
expect(Problem.inputAjax.callCount).toEqual(1); expect(Problem.inputAjax.callCount).toEqual(1);
// Use `.toEqual` rather than `.toHaveBeenCalledWith` // Use `.toEqual` rather than `.toHaveBeenCalledWith`
// since it supports `jasmine.any`. // since it supports `jasmine.any`.
expect(Problem.inputAjax.mostRecentCall.args).toEqual([ expect(Problem.inputAjax.mostRecentCall.args).toEqual([
"THE_URL", "THE_URL",
"THE_ID", "THE_ID",
"preview_formcalc", "preview_formcalc",
{formula: "prefilled_value", {formula: "prefilled_value",
request_start: jasmine.any(Number)}, request_start: jasmine.any(Number)},
jasmine.any(Function) jasmine.any(Function)
]); ]);
});
}); });
it('makes a request on user input', function () { it('makes a request on user input', function () {
formulaEquationPreview.enable(); Problem.inputAjax.reset();
$('#input_THE_ID').val('user_input').trigger('input'); $('#input_THE_ID').val('user_input').trigger('input');
// This part is probably asynchronous // This part is probably asynchronous
...@@ -122,8 +118,7 @@ describe("Formula Equation Preview", function () { ...@@ -122,8 +118,7 @@ describe("Formula Equation Preview", function () {
}); });
it("shouldn't be requested for empty input", function () { it("shouldn't be requested for empty input", function () {
formulaEquationPreview.enable(); Problem.inputAjax.reset();
MathJax.Hub.Queue.reset();
// When we make an input of '', // When we make an input of '',
$('#input_THE_ID').val('').trigger('input'); $('#input_THE_ID').val('').trigger('input');
...@@ -142,9 +137,7 @@ describe("Formula Equation Preview", function () { ...@@ -142,9 +137,7 @@ describe("Formula Equation Preview", function () {
}); });
it('should limit the number of requests per second', function () { it('should limit the number of requests per second', function () {
formulaEquationPreview.enable(); var minDelay = formulaEquationPreview.minDelay;
var minDelay = formulaEquationPreview.minDelay;
var end = Date.now() + minDelay * 1.1; var end = Date.now() + minDelay * 1.1;
var step = 10; // ms var step = 10; // ms
...@@ -179,23 +172,35 @@ describe("Formula Equation Preview", function () { ...@@ -179,23 +172,35 @@ describe("Formula Equation Preview", function () {
describe("Visible results (icon and mathjax)", function () { describe("Visible results (icon and mathjax)", function () {
it('should display a loading icon when requests are open', function () { it('should display a loading icon when requests are open', function () {
formulaEquationPreview.enable();
var $img = $("img.loading"); var $img = $("img.loading");
expect($img.css('visibility')).toEqual('hidden'); expect($img.css('visibility')).toEqual('hidden');
formulaEquationPreview.enable();
$("#input_THE_ID").val("different").trigger('input');
expect($img.css('visibility')).toEqual('visible'); expect($img.css('visibility')).toEqual('visible');
// This part could be asynchronous
waitsFor(function () {
return Problem.inputAjax.wasCalled;
}, "AJAX never called initially", 1000);
runs(function () {
expect($img.css('visibility')).toEqual('visible');
// Reset and send another request.
$img.css('visibility', 'hidden');
$("#input_THE_ID").val("different").trigger('input');
expect($img.css('visibility')).toEqual('visible');
});
// Don't let it fail later. // Don't let it fail later.
waitsFor(function () { waitsFor(function () {
return Problem.inputAjax.wasCalled; var args = Problem.inputAjax.mostRecentCall.args;
return args[3].formula == "different";
}); });
}); });
it('should update MathJax and loading icon on callback', function () { it('should update MathJax and loading icon on callback', function () {
formulaEquationPreview.enable(); formulaEquationPreview.enable();
$('#input_THE_ID').val('user_input').trigger('input');
waitsFor(function () { waitsFor(function () {
return Problem.inputAjax.wasCalled; return Problem.inputAjax.wasCalled;
}, "AJAX never called initially", 1000); }, "AJAX never called initially", 1000);
...@@ -223,12 +228,44 @@ describe("Formula Equation Preview", function () { ...@@ -223,12 +228,44 @@ describe("Formula Equation Preview", function () {
}); });
}); });
it('finds alternatives if MathJax hasn\'t finished loading', function () {
formulaEquationPreview.enable();
$('#input_THE_ID').val('user_input').trigger('input');
waitsFor(function () {
return Problem.inputAjax.wasCalled;
}, "AJAX never called initially", 1000);
runs(function () {
var args = Problem.inputAjax.mostRecentCall.args;
var callback = args[4];
// Cannot find MathJax.
MathJax.Hub.getAllJax.andReturn([]);
spyOn(console, 'error');
callback({
preview: 'THE_FORMULA',
request_start: args[3].request_start
});
// Tests.
expect(console.error).toHaveBeenCalled();
// We should look in the preview div for the MathJax.
var previewElement = $("div")[0];
expect(previewElement.firstChild.data).toEqual("\\[THE_FORMULA\\]");
// Refresh the MathJax.
expect(MathJax.Hub.Queue).toHaveBeenCalledWith(
['Typeset', jasmine.any(Object), jasmine.any(Element)]
);
});
});
it('should display errors from the server well', function () { it('should display errors from the server well', function () {
var $img = $("img.loading"); var $img = $("img.loading");
formulaEquationPreview.enable(); formulaEquationPreview.enable();
MathJax.Hub.Queue.reset();
$("#input_THE_ID").val("different").trigger('input');
waitsFor(function () { waitsFor(function () {
return Problem.inputAjax.wasCalled; return Problem.inputAjax.wasCalled;
}, "AJAX never called initially", 1000); }, "AJAX never called initially", 1000);
...@@ -263,16 +300,14 @@ describe("Formula Equation Preview", function () { ...@@ -263,16 +300,14 @@ describe("Formula Equation Preview", function () {
describe('Multiple callbacks', function () { describe('Multiple callbacks', function () {
beforeEach(function () { beforeEach(function () {
formulaEquationPreview.enable(); formulaEquationPreview.enable();
MathJax.Hub.Queue.reset();
$('#input_THE_ID').val('different').trigger('input');
waitsFor(function () { waitsFor(function () {
return Problem.inputAjax.wasCalled; return Problem.inputAjax.wasCalled;
}); });
runs(function () { runs(function () {
$("#input_THE_ID").val("different2").trigger('input'); $('#input_THE_ID').val('different').trigger('input');
}); });
waitsFor(function () { waitsFor(function () {
return Problem.inputAjax.callCount > 1; return Problem.inputAjax.callCount > 1;
......
...@@ -32,8 +32,7 @@ formulaEquationPreview.enable = function () { ...@@ -32,8 +32,7 @@ formulaEquationPreview.enable = function () {
// Store the DOM/MathJax elements in which visible output occurs. // Store the DOM/MathJax elements in which visible output occurs.
$preview: $preview, $preview: $preview,
// Note: sometimes MathJax hasn't finished loading yet. jax: null, // Fill this in later.
jax: MathJax.Hub.getAllJax($preview[0])[0],
$img: $preview.find("img.loading"), $img: $preview.find("img.loading"),
requestCallback: null // Fill it in in a bit. requestCallback: null // Fill it in in a bit.
...@@ -59,7 +58,7 @@ formulaEquationPreview.enable = function () { ...@@ -59,7 +58,7 @@ formulaEquationPreview.enable = function () {
$this.on("input", initializeRequest); $this.on("input", initializeRequest);
// send an initial // send an initial
MathJax.Hub.Queue(this, initializeRequest); initializeRequest.call(this);
} }
/** /**
...@@ -127,20 +126,26 @@ formulaEquationPreview.enable = function () { ...@@ -127,20 +126,26 @@ formulaEquationPreview.enable = function () {
function display(latex) { function display(latex) {
// Load jax if it failed before. // Load jax if it failed before.
var previewElement = inputData.$preview[0];
if (!inputData.jax) { if (!inputData.jax) {
results = MathJax.Hub.getAllJax(inputData.$preview[0]); inputData.jax = MathJax.Hub.getAllJax(previewElement)[0];
if (!results.length) {
console.log("Unable to find MathJax to display");
return;
}
inputData.jax = results[0];
} }
// Set the text as the latex code, and then update the MathJax. // MathJax might not be loaded yet (still).
MathJax.Hub.Queue( if (inputData.jax) {
['Text', inputData.jax, latex], // Set the text as the latex code, and then update the MathJax.
['Reprocess', inputData.jax] MathJax.Hub.Queue(
); ['Text', inputData.jax, latex],
['Reprocess', inputData.jax]
);
}
else if (latex) {
console.error("Oops no mathjax for ", latex);
// Fall back to modifying the actual element.
var textNode = previewElement.childNodes[0];
textNode.data = "\\[" + latex + "\\]";
MathJax.Hub.Queue(["Typeset", MathJax.Hub, previewElement]);
}
} }
if (response.error) { if (response.error) {
......
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