Benvenuto su Inforge
Rimuovi la pubblicità e partecipa alla più grande comunità italiana sul mondo digitale presente sul web sin dal 2007.
Iscriviti

Domanda Bug durante il rendering dei vari typeset in LaTeX [con suggerimento per fixare]

nullptr

Utente Gold
26 Novembre 2015
1,088
342
325
Mentre navigavo ho riscontrato questo bug durante il rendering dei diversi typeset per le notazioni matematiche:
Screenshot_2021-07-17 Ricerca sottomatrici in C.png

(Clicca qui per visualizzare il thread, per riprodurre il bug basta aggiornare la pagina una o più volte.)

Ho dato un occhio al codice dello script che avvia la procedura per il rendering:
JavaScript:
window.MathJax = {
    loader: {
        load: ["ui/safe"]
    },
    options: {
        enableMenu: !1
    },
    tex: {
        inlineMath: [
            ["$$\\(", "$$\\)"]
        ],
        displayMath: [
            ["$$\\[", "$$\\]"]
        ],
        processEscapes: !1,
        processRefs: !0,
        processEnvironments: !1,
        tags: "ams"
    },
    svg: {
        fontCache: "global"
    }
};
(function() {
    var a = document.createElement("script");
    a.src = "https://cdn.jsdelivr.net/npm/[email protected]/es5/tex-svg.js";
    a.async = !0;
    document.head.appendChild(a)
})();
var retypesetDisabled = !1;

function retypesetMathjax() {
    $(this).off("DOMSubtreeModified", retypesetMathjax);
    retypesetDisabled ? setTimeout(retypesetMathjax, 500) : (retypesetDisabled = !0, $(this).on("DOMSubtreeModified", retypesetMathjax), window.MathJax.typesetPromise().then(function() {
        retypesetDisabled = !1
    })["catch"](function(a) {
        return console.log(a.message)
    }))
}
$(window).on("load", function() {
    $("article.message, article.resourceBody-main, blockquote.message-body").each(function() {
        $(this).on("DOMSubtreeModified", retypesetMathjax)
    })
});

ed ho notato che viene impostato un event handler per l'evento load della finestra. È qui il problema: window.onload viene triggerato quando la finestra del documento è pronta per la presentazione mentre document.onload viene triggerato quando la struttura del DOM è stata caricata completamente.
window.onload viene triggerato due volte quando è chiamato dentro l'elemento body dell'albero del documento (come in questo caso, lo script è caricato dal body e causa un doppio rendering), mentre una volta sola quando è dichiarato dentro l'elemento head agendo come il secondo.

Le due più semplici delle varie soluzioni sono:

  1. Caricare lo script per il rendering nell'elemento head anzichè nel body.
  2. Far sì che l'event handler per il tipo di evento load sia subito svincolato dopo la prima invocazione attraverso il metodo one() anzichè on():
JavaScript:
$(window).one("load", function() {
    $("article.message, article.resourceBody-main, blockquote.message-body").each(function() {
        $(this).on("DOMSubtreeModified", retypesetMathjax)
    })
});

Questo è il codice fixato e minimizzato:
JavaScript:
window.MathJax={loader:{load:["ui/safe"]},options:{enableMenu:!1},tex:{inlineMath:[["$$\\(","$$\\)"]],displayMath:[["$$\\[","$$\\]"]],processEscapes:!1,processRefs:!0,processEnvironments:!1,tags:"ams"},svg:{fontCache:"global"}},function(){var e=document.createElement("script");e.src="https://cdn.jsdelivr.net/npm/[email protected]/es5/tex-svg.js",e.async=!0,document.head.appendChild(e)}();var retypesetDisabled=!1;function retypesetMathjax(){$(this).off("DOMSubtreeModified",retypesetMathjax),retypesetDisabled?setTimeout(retypesetMathjax,500):(retypesetDisabled=!0,$(this).on("DOMSubtreeModified",retypesetMathjax),window.MathJax.typesetPromise().then(function(){retypesetDisabled=!1}).catch(function(e){return console.log(e.message)}))}$(window).one("load",function(){$("article.message, article.resourceBody-main, blockquote.message-body").each(function(){$(this).on("DOMSubtreeModified",retypesetMathjax)})});
 
  • Mi piace
Reactions: Dany Dollaro

SpeedJack

Super Moderatore
Super Moderatore
18 Febbraio 2010
8,514
3,844
1,209
Lo so già, ma in realtà dobbiamo usare gli eventi del framework js di xenforo per evitare altri problemi.
Sarà sistemato, dopo altre cose maggiormente prioritarie.
 
  • Mi piace
Reactions: Max Fridman

nullptr

Utente Gold
26 Novembre 2015
1,088
342
325
@SpeedJack: non ho idea di cosa tu voglia intendere con “dobbiamo usare gli eventi del framework js di xenforo per evitare altri problemi”. Quali eventi? Di quali problemi parli?

Vedrai che non ti costa nulla un copia-incolla del mio codice, e fixerà il bug.
 

SpeedJack

Super Moderatore
Super Moderatore
18 Febbraio 2010
8,514
3,844
1,209
@SpeedJack: non ho idea di cosa tu voglia intendere con “dobbiamo usare gli eventi del framework js di xenforo per evitare altri problemi”
XenForo ha un suo framework js interno che definisce anche altri eventi js. Cè un meccanismo che serve a garantire la corretta esecuzione ordinata degli script di tutti gli addon e di quelli interni di xenforo. Xenforo definisce anche dei suoi eventi interni: gli addon non dovrebbero mai registrarsi agli eventi usando on() o one() ma XF.Event.register().
Ad esempio, puoi verificare che se editi un post con dentro del codice LaTeX, dopo aver premuto su salva il rendering non avviene finché non ricarichi la pagina. Xenforo permette di registrare degli handler che vengano eseguiti ogniqualvolta sia necessario rieffettuare il rendering di un post.

L'addon va riscritto nel modo corretto perché si integri e non abbia problemi con XF. Facendolo in questo modo, risolverà anche il problema che hai segnalato. Lo farò, però subito dopo aver sistemato la grid o Max mi picchia - entro estate.
 
Rodnia -  The Great Conqueror
Supporta Inforge con un acquisto su NordVPN

nullptr

Utente Gold
26 Novembre 2015
1,088
342
325
@SpeedJack: non ho idea se tu abbia ragione o meno dato che non conosco XenForo.
In questo e questo post, anche se vecchi di un po' di anni, lo sviluppatore di XenForo e un altro utente ovviano allo stesso (o simile) problema con una soluzione analoga a quelle che ho proposto.
In questo modo non viene utilizzato nè on() e nè one(), anche se DOMready e window.onload non sono uguali e il rendering forse potrebbe caricare dopo qualche secondo in uno mentre in un altro no.