diff --git a/ts/components/startup.ts b/ts/components/startup.ts index 7ceae5ea4..9c2a324b3 100644 --- a/ts/components/startup.ts +++ b/ts/components/startup.ts @@ -96,6 +96,7 @@ export interface MathJaxObject extends MJObject { elements: any[]; document: MATHDOCUMENT; promise: Promise; + rerenderPromise: Promise; /* tslint:disable:jsdoc-require */ registerConstructor(name: string, constructor: any): void; useHandler(name: string, force?: boolean): void; @@ -184,7 +185,7 @@ export namespace Startup { /** * The promise for the startup process (the initial typesetting). - * It is resolves or rejected in the ready() function. + * It is resolved or rejected in the ready() function. */ export let promise = new Promise((resolve, reject) => { promiseResolve = resolve; @@ -206,6 +207,13 @@ export namespace Startup { } }); + /** + * Non-null when MathJax.typeset() or MathJax.typesetPromise() have been performed + * (so the menu code can tell whether a rerender is needed when components are loaded) + * and then is equal to a promise after which rerendering can occur. + */ + export let rerenderPromise: Promise = null; + /** * @param {MmlNode} node The root of the tree to convert to serialized MathML * @return {string} The serialized MathML from the tree @@ -374,9 +382,12 @@ export namespace Startup { document.options.elements = elements; document.reset(); document.render(); + if (!rerenderPromise) { + rerenderPromise = promise; + } }; MathJax.typesetPromise = (elements: any[] = null) => { - promise = promise.then(() => typesetPromise(elements)); + rerenderPromise = promise = promise.then(() => typesetPromise(elements)); return promise; }; MathJax.typesetClear = (elements: any[] = null) => { diff --git a/ts/ui/menu/Menu.ts b/ts/ui/menu/Menu.ts index de861d8a1..3f4478efc 100644 --- a/ts/ui/menu/Menu.ts +++ b/ts/ui/menu/Menu.ts @@ -1175,18 +1175,23 @@ export class Menu { /** * Rerender the output if we aren't in the middle of loading a new component - * (in which case, we will rerender in the callback performed after it is loaded) + * (in which case, we will rerender in the callback performed after it is loaded) * * @param {number=} start The state at which to start rerendering */ protected rerender(start: number = STATE.TYPESET) { this.rerenderStart = Math.min(start, this.rerenderStart); - if (!Menu.loading) { - if (this.rerenderStart <= STATE.COMPILED) { - this.document.reset({inputJax: []}); - } - this.document.rerender(this.rerenderStart); - this.rerenderStart = STATE.LAST; + const startup = MathJax.startup; + if (!Menu.loading && startup.rerenderPromise) { + startup.rerenderPromise = startup.promise = startup.rerenderPromise.then( + () => mathjax.handleRetriesFor(() => { + if (this.rerenderStart <= STATE.COMPILED) { + this.document.reset({inputJax: []}); + } + this.document.rerender(this.rerenderStart); + this.rerenderStart = STATE.LAST; + }) + ); } }