Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit e9a0838

Browse files
committed
Progress on moving the lifting to the base class
1 parent a358768 commit e9a0838

File tree

3 files changed

+82
-7
lines changed

3 files changed

+82
-7
lines changed

runestone/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ def setup(app):
112112
This could be expanded if there is additional initialization or customization
113113
we wanted to do for all projects.
114114
"""
115+
# This tells the mathjax extension to always load mathjax.
116+
# This should save some configuration headaches as we transition from RST to PTX
117+
app.set_html_assets_policy("always")
115118
# Include JS and CSS produced by webpack. See `webpack static imports <webpack_static_imports>`_.
116119
with open(
117120
pkg_resources.resource_filename(

runestone/common/js/runestonebase.js

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ export default class RunestoneBase {
7373
}
7474
this.is_toggle = true ? opts.is_toggle : false;
7575
this.is_select = true ? opts.is_select : false;
76+
7677
}
78+
this.mjelements = [];
7779
this.jsonHeaders = new Headers({
7880
"Content-type": "application/json; charset=utf-8",
7981
Accept: "application/json",
@@ -444,17 +446,79 @@ export default class RunestoneBase {
444446

445447
queueMathJax(component) {
446448
if (typeof(MathJax) === "undefined") {
449+
console.log("Error -- MathJax is not loaded")
447450
return Promise.resolve(null);
448-
}
449-
if (MathJax.version.substring(0, 1) === "2") {
450-
MathJax.Hub.Queue(["Typeset", MathJax.Hub, component]);
451451
} else {
452452
// See - https://docs.mathjax.org/en/latest/advanced/typeset.html
453453
// Per the above we should keep track of the promises and only call this
454454
// a second time if all previous promises have resolved.
455-
return MathJax.typesetPromise([component]);
455+
// Create a queue of components
456+
// should wait until defaultPageReady is defined
457+
// If defaultPageReady is not defined then just enqueue the components.
458+
// Once defaultPageReady is defined
459+
if (MathJax.startup && MathJax.startup.defaultPageReady) {
460+
return MathJax.startup.defaultPageReady().then(
461+
async function() {
462+
console.log(`MathJax Ready -- promising a typesetting run for ${component.id}`)
463+
return await MathJax.typesetPromise([component])
464+
}
465+
);
466+
}
456467
}
457468
}
469+
470+
}
471+
472+
473+
// Inspiration and lots of code for this solution come from
474+
// https://stackoverflow.com/questions/53540348/js-async-await-tasks-queue
475+
// The idea here is that until MathJax is ready we can just enqueue things
476+
// once mathjax becomes ready then we can drain the queue and continue as usual.
477+
478+
class Queue {
479+
constructor() { this._items = []; }
480+
enqueue(item) { this._items.push(item); }
481+
dequeue() { return this._items.shift(); }
482+
get size() { return this._items.length; }
483+
}
484+
485+
class AutoQueue extends Queue {
486+
constructor() {
487+
super();
488+
this._pendingPromise = false;
489+
}
490+
491+
enqueue(action) {
492+
return new Promise((resolve, reject) => {
493+
super.enqueue({ action, resolve, reject });
494+
this.dequeue();
495+
});
496+
}
497+
498+
async dequeue() {
499+
if (this._pendingPromise) return false;
500+
501+
let item = super.dequeue();
502+
503+
if (!item) return false;
504+
505+
try {
506+
this._pendingPromise = true;
507+
508+
let payload = await item.action(this);
509+
510+
this._pendingPromise = false;
511+
item.resolve(payload);
512+
} catch (e) {
513+
this._pendingPromise = false;
514+
item.reject(e);
515+
} finally {
516+
this.dequeue();
517+
}
518+
519+
return true;
520+
}
458521
}
459522

523+
460524
window.RunestoneBase = RunestoneBase;

runestone/parsons/js/parsons.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -464,9 +464,16 @@ export default class Parsons extends RunestoneBase {
464464
// outerHeight can be unreliable if elements are not yet visible
465465
// outerHeight will return bad results if MathJax has not rendered the math
466466
areaWidth = 300;
467+
let self = this;
467468
maxFunction = async function(item) {
468469
if (this.options.language == "natural" || this.options.language == "math") {
469-
await this.queueMathJax(item[0])
470+
if (typeof runestoneMathready !== "undefined") {
471+
await runestoneMathReady.then(async () => await self.queueMathJax(item[0]));
472+
} else { // this is for older rst builds not ptx
473+
if (typeof MathJax.startup !== "undefined") {
474+
await self.queueMathJax(item[0]);
475+
}
476+
}
470477
}
471478
areaWidth = Math.max(areaWidth, item.outerWidth(true));
472479
item.width(areaWidth - 22);
@@ -570,12 +577,13 @@ export default class Parsons extends RunestoneBase {
570577
this.blocks[i].initializeInteractivity();
571578
}
572579
this.initializeTabIndex();
580+
let self = this;
573581
if (
574582
this.options.language == "natural" ||
575583
this.options.language == "math"
576584
) {
577-
if (typeof MathJax !== "undefined") {
578-
this.queueMathJax(this.outerDiv);
585+
if (typeof MathJax.startup !== "undefined") {
586+
self.queueMathJax(self.outerDiv);
579587
}
580588
}
581589
}

0 commit comments

Comments
 (0)