Adds a translate buttons for character messages in the chat for beta.character.ai
目前為
// ==UserScript==
// @name Translate Buttons for beta.character.ai
// @namespace TranslateButtonsForBetaCharacterAI
// @description Adds a translate buttons for character messages in the chat for beta.character.ai
// @version 2.0.3
// @author CriDos
// @icon https://www.google.com/s2/favicons?sz=64&domain=beta.character.ai
// @match https://beta.character.ai/chat?char=*
// @grant GM_xmlhttpRequest
// @run-at document-end
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js
// @license MIT
// ==/UserScript==
'use strict';
console.log(`Translate Buttons initializing...`);
let debug = true;
setInterval(addTranslateButtons, 1000);
async function addTranslateButtons() {
var charMessages = document.getElementsByClassName("char-msg");
for (var i = 0; i < charMessages.length; i++) {
const node = charMessages[i].querySelector(".markdown-wrapper");
if (node == null) {
continue;
}
const parentNode = node.parentElement;
if (parentNode.isAutoTranslate) {
continue;
}
parentNode.isAutoTranslate = true;
setInterval(async () => {
await translateNode(node);
}, 500);
}
}
async function translateNode(node) {
const translateClassName = "translate";
const parentNode = node.parentElement;
const nodeContent = $(node).html();
if (node.storeContent == nodeContent) {
return;
}
node.storeContent = nodeContent;
var translateNode = parentNode.querySelector(`.${translateClassName}`);
if (translateNode == null) {
translateNode = node.cloneNode(true);
translateNode.classList.add(translateClassName);
parentNode.insertBefore(translateNode, parentNode.firstChild);
}
var nodeClone = node.cloneNode(true);
nodeClone.classList.add(translateClassName);
const nodeCloneContent = $(nodeClone).html();
nodeClone = null;
var translatedContent = await translateText(nodeCloneContent, "en", navigator.language)
translatedContent = translatedContent.replace('< div>', '<div>')
translatedContent = translatedContent.replace('< дел>', '<div>')
translatedContent = translatedContent.replace('<дел>', '<div>')
translatedContent = translatedContent.replace('< /div>', '</div>')
translatedContent = translatedContent.replace('< /дел>', '</div>')
translatedContent = translatedContent.replace('</дел>', '</div>')
translatedContent = translatedContent.replace('< p>', '<p>')
translatedContent = translatedContent.replace('< /p>', '</p>')
translatedContent = translatedContent.replace(/<\/div>$/, '');
$(translateNode).html(translatedContent + "<p>.......... end_translate ..........</p></div>");
}
async function translateText(text, sLang, tLang) {
const url = `https://translate.googleapis.com/translate_a/single?client=gtx&format=text&sl=${sLang}&tl=${tLang}&dt=t&q=${encodeURIComponent(text)}`;
try {
if (debug) {
console.log(`preTranslate: ${text}`);
}
const response = await doXHR(url);
const responseText = JSON.parse(response.responseText);
let postTranslate = "";
responseText[0].forEach(part => {
postTranslate += part[0];
});
if (debug) {
console.log(`postTranslate: ${postTranslate}`);
}
return postTranslate;
} catch (error) {
console.error(error);
}
}
async function doXHR(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}