Twitch Translate Chat Messages

Translate Twitch Chat Messages via Double-Click

当前为 2018-05-12 提交的版本,查看 最新版本

// ==UserScript==
// @name          Twitch Translate Chat Messages
// @namespace     http://userstyles.org
// @description   Translate Twitch Chat Messages via Double-Click
// @author        636597
// @include       *://*.twitch.tv/*
// @run-at        document-start
// @version       0.4
// ==/UserScript==


// https://console.cloud.google.com/apis/credentials
var destinationLanguage = "en";
var gapi_key = "";

var HttpClient = function() {
    this.post = function( aUrl , aQueryString ,  aCallback ) {
        var anHttpRequest = new XMLHttpRequest();
        anHttpRequest.onreadystatechange = function() { 
            if ( anHttpRequest.readyState == 4 && anHttpRequest.status == 200 ) {
                aCallback( anHttpRequest.responseText );
            }
        };
        anHttpRequest.open( "POST", aUrl , true );
        anHttpRequest.setRequestHeader( "Content-Type" , "application/x-www-form-urlencoded; charset=UTF-8" );
        anHttpRequest.send( aQueryString );
    };
};

function fixedEncodeURIComponent(str){
    return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}

var TranslationActive = false;
var client = null;
var GoogleTranslateBase = "https://translation.googleapis.com/language/translate/v2";
var GoogleTranslateEnd = "&key=" + gapi_key;

var TranB1 = "q=";
var TranB2 = "&target=" + destinationLanguage;
function translateText( text , dom_elem ) {
    text = text.trim();
    var query_string = TranB1 + fixedEncodeURIComponent( text ) + TranB2 + GoogleTranslateEnd;
    client.post( GoogleTranslateBase , query_string , function(response) {
        var translation = JSON.parse( response );
        translation = translation[ "data" ][ "translations" ][ 0 ][ "translatedText" ];
        translation = translation.trim();
        for ( var i = 0; i < dom_elem.childNodes.length; ++i ) {
            var attr = dom_elem.childNodes[ i ].getAttribute( "data-a-target" );
            if ( attr === "chat-message-text" ) {
                dom_elem.childNodes[ i ].innerHTML = translation;
                break;
            }
        }
        dom_elem.setAttribute( "data-showTranslation" ,  "true" );
        dom_elem.setAttribute( "data-translatedText" , translation );
        dom_elem.setAttribute( "data-originalText" ,  text );
    }); 
}

var chat_element = null;
var chat_observer = null;
var observerConfig = {
    attributes: true,
    childList: true,
    characterData: true
};
function loadObserver() {
    chat_observer = new MutationObserver(function(mutations) {
        mutations.forEach(function( mutation , index ) {
            if ( mutation.type === "childList" ) {
                var addedNode = mutation.addedNodes[0];
                if( addedNode ) {
                    var msg = addedNode.innerText;
                    if ( TranslationActive ) {
                        addedNode.addEventListener( "dblclick" , function() {
                            var show_translation = addedNode.getAttribute( "data-showTranslation" );
                            if ( show_translation ) {
                                if ( show_translation === "true" ) {
                                    var original_text = addedNode.getAttribute( "data-originalText" );
                                    for ( var i = 0; i < addedNode.childNodes.length; ++i ) {
                                        var attr = addedNode.childNodes[ i ].getAttribute( "data-a-target" );
                                        if ( attr === "chat-message-text" ) {
                                            addedNode.childNodes[ i ].innerText = original_text;
                                            break;
                                        }
                                    }
                                    addedNode.setAttribute( "data-showTranslation" , "false" );
                                }
                                else {
                                    addedNode.setAttribute( "data-showTranslation" ,  "true" );
                                    var already_translated = addedNode.getAttribute( "data-translatedText" );
                                    for ( var i = 0; i < addedNode.childNodes.length; ++i ) {
                                        var attr = addedNode.childNodes[ i ].getAttribute( "data-a-target" );
                                        if ( attr === "chat-message-text" ) {
                                            addedNode.childNodes[ i ].innerHTML = already_translated;
                                            break;
                                        }
                                    }
                                }
                            }
                            else {
                                var z1 = msg.split( ":" )[1];
                                translateText( z1 , addedNode );
                            }
                        } , false );
                    }
                }
            }
        });
    });

    if ( gapi_key && destinationLanguage ) {
        client = new HttpClient();
        TranslationActive = true;
        chat_observer.observe( chat_element , observerConfig );
        console.log( "Twitch Translation Loaded" );
    }
    
}


(function() {
    var ready = setInterval(function(){
        var x1 = document.querySelectorAll( '[role="log"]' );
        if ( x1 ) { if ( x1[ 0 ] ) { chat_element = x1[0]; clearInterval( ready ); loadObserver(); } }
    } , 2 );
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址