Created
May 14, 2023 20:56
-
-
Save fluteds/c33fe720e180137ab06642afd736e76c to your computer and use it in GitHub Desktop.
Shows English translations when Korean text is hovered over on b.stage via Google Translate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name ATEEZ b.stage Translator | |
// @version 1.0 | |
// @author Fluteds | |
// @description Shows English translations when Korean text is hovered over on b.stage via Google Translate. | |
// @match https://ateez.kqent.com/* | |
// @icon https://static.musictoday.com/store/bands/6099/images/favicon.ico | |
// @grant GM_xmlhttpRequest | |
// ==/UserScript== | |
// TODO: Target post and OP comment reply chains content only | |
// Create a tooltip element for displaying translations | |
const tooltip = document.createElement('div'); | |
tooltip.style.position = 'fixed'; | |
tooltip.style.zIndex = '9999'; | |
tooltip.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; | |
tooltip.style.padding = '5px'; | |
tooltip.style.borderRadius = '3px'; | |
tooltip.style.color = '#fff'; | |
tooltip.style.fontFamily = 'Arial, sans-serif'; | |
tooltip.style.fontSize = '14px'; | |
tooltip.style.maxWidth = '400px'; // Adjust the maximum width as needed | |
tooltip.style.wordWrap = 'break-word'; // Enable word wrapping | |
tooltip.style.display = 'none'; | |
document.body.appendChild(tooltip); | |
// Function to handle hover event and translation | |
function handleHover(event) { | |
const text = event.target.textContent; | |
const isExcludedClass = isExcludedElement(event.target); | |
if (isKorean(text) && !isExcludedClass) { | |
translate(text, event.clientX, event.clientY); | |
} | |
} | |
function isExcludedElement(element) { | |
const excludedClasses = ["UserInfo_subText__EP_i7", "Reactions_container__WFkfN"]; | |
for (const className of excludedClasses) { | |
if (element.classList.contains(className)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
// Function to check if text is in Korean | |
function isKorean(text) { | |
const koreanPattern = /[ㄱ-ㅎㅏ-ㅣ가-힣]/; | |
return koreanPattern.test(text); | |
} | |
// Function to translate Korean text to English | |
function translate(text, x, y) { | |
const encodedText = encodeURIComponent(text); | |
GM_xmlhttpRequest({ | |
method: 'GET', | |
url: `https://translate.googleapis.com/translate_a/single?client=gtx&sl=ko&tl=en&dt=t&q=${encodedText}`, | |
onload: function(response) { | |
const translations = JSON.parse(response.responseText)[0]; | |
const translation = translations.reduce((acc, cur) => acc + cur[0], ''); | |
const decodedTranslation = decodeEntities(translation); | |
tooltip.innerHTML = decodedTranslation; | |
tooltip.style.display = 'block'; | |
tooltip.style.left = getTooltipXPosition(x); | |
tooltip.style.top = getTooltipYPosition(y); | |
} | |
}); | |
} | |
// Decode HTML entities | |
function decodeEntities(encodedString) { | |
const textArea = document.createElement('textarea'); | |
textArea.innerHTML = encodedString; | |
return textArea.value; | |
} | |
// Calculate the X position of the tooltip | |
function getTooltipXPosition(clientX) { | |
const tooltipWidth = tooltip.offsetWidth; | |
const windowWidth = window.innerWidth; | |
const maxPosition = windowWidth - tooltipWidth - 10; // Leave 10px padding | |
return Math.min(clientX + 10, maxPosition) + 'px'; | |
} | |
// Calculate the Y position of the tooltip | |
function getTooltipYPosition(clientY) { | |
const tooltipHeight = tooltip.offsetHeight; | |
const windowHeight = window.innerHeight; | |
const maxPosition = windowHeight - tooltipHeight - 10; // Leave 10px padding | |
return Math.min(clientY + 10, maxPosition) + 'px'; | |
} | |
// Add event listeners to handle hover and hide tooltip | |
document.addEventListener('mouseover', handleHover); | |
document.addEventListener('mouseout', function(event) { | |
if (!tooltip.contains(event.relatedTarget)) { | |
tooltip.style.display = 'none'; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment