Greasy Fork is available in English.
Double-Click to Translate Twitch Chat Messages
当前为
// ==UserScript==
// @name Twitch Translate Chat Messages
// @namespace http://userstyles.org
// @description Double-Click to Translate Twitch Chat Messages
// @author 636597
// @include *://*.twitch.tv/*
// @run-at document-start
// @version 0.5
// ==/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 start = msg.indexOf( ":" );
var z1 = msg.substring( ( start + 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 );
})();