naovoupensaremumnome / MathJax no ChatStep (MathJax on ChatStep)

// ==UserScript==
// @name     MathJax no ChatStep (MathJax on ChatStep)
// @author   Vinícius
// @match    http://chatstep.com/*
// @match    https://chatstep.com/*
// ==/UserScript==

main_ = function() {
  
    // carregar o MathJax 
    // (load MathJax)
    (function () {
        var head = document.getElementsByTagName("head")[0], script;
        script = document.createElement("script");
        script.type = "text/x-mathjax-config";
        script[(window.opera ? "innerHTML" : "text")] =
          "MathJax.Hub.Config({\n" +
          "  tex2jax: { inlineMath: [['$','$'],['\\\\(','\\\\)']]," +
                  "displayMath: [['$$','$$'],['\\\\[','\\\\]']]" +
              "}\n" +
          "});"
        head.appendChild(script);
        script = document.createElement("script");
        script.type = "text/javascript";
        script.src  = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
        head.appendChild(script);
    })();
    
    
    var idUltBolha = "";         // id da última bolha (last bubble's id)
    var bolhaDigitando = false;  // verdadeiro se há uma bolha "digitando" (true if there's a "typing" bubble)
    var texto = "";              // último texto no campo de entrada (last text in input field)
    
    
    // chama o MathJax e corrige a altura da bolha
    // a classe de ultbolha é "bubbleFrame", e a classe de conteudo é o nome da cor
    // (calls MathJax and sets the bubble's height)
    // (ultbolha's class is "bubbleFrame" and conteudo's class is its color name)
    atualizarBolha = function (ultbolha, conteudo) {
      
        // enfileirar para MathJax interpretar última bolha
        // (enqueue last bubble for MathJax to render)
        MathJax.Hub.Queue(["Typeset",MathJax.Hub, ultbolha]);
        
        // após MathJax interpretar a última bolha, ajustar a altura dela
        // (after MathJax interprets the last bubble, set up its height)
        MathJax.Hub.Queue(function() {
           ultbolha.style.height = conteudo.clientHeight + 10;
           });
           
        // descer barra de rolagem até o fim
        // (scroll to bottom)
        document.getElementById("transcript").scrollTop=document.getElementById("transcript").scrollHeight;
    }
    
    // substitui função que adiciona bolha:
    // (overrides function that adds a bubble:)
    createBubble_ = createBubble;
  
    createBubble = function (nick, unique, body, me) {
      
        // se agora é uma mensagem real -- não uma bolha "digitando" e já há uma bolha "digitando", então remova-a
        // (if now it's a real message -- not a "typing" bubble -- and there's a "typing" bubble, then remove that)
        if (nick.length > 0 && bolhaDigitando)
            removerBolhaDigitando();
            
        // chama a função original
        // (calls the original function)
        createBubble_(nick, unique, body, me);
        
        bolhas = document.getElementById("transcript").getElementsByClassName("bubbleFrame");
        ultbolha = bolhas[bolhas.length - 1];
        idUltBolha = ultbolha.id;
        conteudo = ultbolha.getElementsByClassName(roomData[unique]["color"])[0];
        
        // retirar limitação de largura 300px
        // (remove 300px width limit)
        conteudo.style.width = "";
        
        // largura máxima da bolha = 80% da largura do "transcript"
        // (maximum bubble's width = 0.8 x transcript's width)
        conteudo.style.maxWidth = parseInt(document.getElementById("transcript").style.width)*0.8;
        
        // atualizar MathJax e a altura
        // (update MathJax and the height)
        atualizarBolha(ultbolha, conteudo);
    }
    
    // cria uma bolha com fundo branco que mostra a visualização da mensagem que está sendo digitada
    // (creates a bubble with white background that shows the preview of the message that's being typed)
    function criarBolhaDigitando() {
      
        bolhaDigitando = true;
        
        // com nome vazio
        // (with empty nickname)
        createBubble("", global_user_id, parseMessage(document.getElementById("message").value)[0], true);
        
        ultbolha = document.getElementById(idUltBolha);
        
        // ocultar horário da bolha "digitando"
        // (hide timespan of "typing" bubble)
        ultbolha.getElementsByClassName("timeSpan")[0].style.display = "none";
        
        conteudo = ultbolha.getElementsByClassName(roomData[global_user_id]["color"])[0];
        
        // fundo branco
        // (white background)
        conteudo.style.backgroundColor = "white";
    }


    // remove a bolha "digitando" 
    // (removes "typing" bubble)
    function removerBolhaDigitando() {
        document.getElementById("transcript").removeChild(document.getElementById(idUltBolha));
        bolhaDigitando = false;
        texto = "";
    }
    
    // verifica se é preciso alterar a bolha "digitando"
    // (checks if now we need to update the "typing" bubble)
    verificar = function() {
      
        textoAtual = document.getElementById("message").value; // (get current text in input field)
        
        // se o usuário apagou tudo e ainda tem uma bolha "digitando", remova-a
        // (if the users cleared the input field and there's still a "typing" bubble, remove it)
        if (textoAtual.length == 0 && bolhaDigitando)
            removerBolhaDigitando();
        else if (textoAtual != texto) { // se o texto foi modificado (if the text has changed)
            texto = textoAtual;
            if (!bolhaDigitando) // se não havia bolha "digitando", crie-a (if there's no "typing" bubble, create it)
                criarBolhaDigitando();
            else {               // se já tem a bolha, basta atualizar (if the bubble has already been created, just update it)
                ultbolha = document.getElementById(idUltBolha);
                conteudo = ultbolha.getElementsByClassName(roomData[global_user_id]["color"])[0];
                conteudo.getElementsByClassName("bubbleBody")[0].innerHTML = parseMessage(document.getElementById("message").value)[0];   
                // atualizar MathJax e a altura
                // (update MathJax and the height)
                atualizarBolha(ultbolha, conteudo);
            }
        }
    }
    
    // ativar horários e notificações sonoras por padrão
    // (enable timestamp and sound notifications by default)
    if (!timeStampGlobal)
        changeTimestamps();
    if (!soundNotifications)
        soundOffF();
        
    // verificar quatro vezes por segundo
    // (check four times per second)
    timerdig = setInterval("verificar();", 250);
}


// adicionar script à página
// (add script to the page)
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ main_ +')();'));
document.head.appendChild(script);