ScWeb_Chinese_Translate/userscript.js

204 lines
5.1 KiB
JavaScript
Raw Normal View History

2023-01-28 01:22:18 +08:00
// ==UserScript==
2022-07-29 12:17:04 +08:00
// @name UEX汉化脚本
// @namespace Violentmonkey Scripts
// @match https://uexcorp.space/*
// @grant none
2023-01-28 01:22:18 +08:00
// @version 0.8.0
// @license GNU GPLv3
2022-07-29 12:17:04 +08:00
// @author CxJuice
// @description 2022/7/28 12:48:01
2023-01-28 01:22:18 +08:00
// @match https://uexcorp.space/*
// @match https://www.erkul.games/*
// @grant GM_xmlhttpRequest
// @grant GM_getResourceText
// @resource zh-CN https://cdn.jsdelivr.net/gh/CxJuice/Uex_Chinese_Translate@main/zh-CN-uex1.7.json
// @require https://cdn.bootcdn.net/ajax/libs/timeago.js/4.0.2/timeago.full.min.js
// @require https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js
2022-07-29 12:17:04 +08:00
// ==/UserScript==
2023-01-28 01:22:18 +08:00
window.addEventListener('load', function(event) {
// 当页面加载完成时,执行我们的脚本
myScript();
});
// 监听页面中的鼠标点击事件
document.addEventListener('click', function(event) {
// 当发生鼠标点击事件时,执行我们的脚本
myScript();
});
function myScript() {
2022-07-29 12:17:04 +08:00
(function() {
'use strict';
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
const SUPPORT_LANG = ["zh-CN", "ja"];
const lang = (navigator.language || navigator.userLanguage);
const locales = getLocales(lang)
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
translateByCssSelector();
translateDesc();
traverseElement(document.body);
watchUpdate();
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
function getLocales(lang) {
if(lang.startsWith("zh")) { // zh zh-TW --> zh-CN
lang = "zh-CN";
}
if(SUPPORT_LANG.includes(lang)) {
return JSON.parse(GM_getResourceText(lang));
}
return {
css: [],
dict: {}
};
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
function translateRelativeTimeEl(el) {
const datetime = $(el).attr('datetime');
$(el).text(timeago.format(datetime, lang.replace('-', '_')));
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
function translateElement(el) {
// Get the text field name
let k;
if(el.tagName === "INPUT") {
if (el.type === 'button' || el.type === 'submit') {
k = 'value';
} else {
k = 'placeholder';
}
} else {
k = 'data';
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
const txtSrc = el[k].trim();
const key = txtSrc.toLowerCase()
.replace(/\xa0/g, ' ') // replace ' '
.replace(/\s{2,}/g, ' ');
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
if(locales.dict[key]) {
el[k] = el[k].replace(txtSrc, locales.dict[key])
}
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
function shoudTranslateEl(el) {
const blockIds = ["readme", "wiki-content"];
const blockClass = [
2023-01-28 01:22:18 +08:00
"mat-icon",
2022-07-29 12:17:04 +08:00
"CodeMirror",
"css-truncate" // 过滤文件目录
];
2023-01-28 01:22:18 +08:00
const blockTags = [];
2022-07-29 12:17:04 +08:00
if(blockTags.includes(el.tagName)) {
return false;
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
if(el.id && blockIds.includes(el.id)) {
return false;
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
if(el.classList) {
for(let clazz of blockClass) {
if(el.classList.contains(clazz)) {
return false;
}
}
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
return true;
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
function traverseElement(el) {
if(!shoudTranslateEl(el)) {
return
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
for(const child of el.childNodes) {
if(["RELATIVE-TIME", "TIME-AGO"].includes(el.tagName)) {
translateRelativeTimeEl(el);
return;
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
if(child.nodeType === Node.TEXT_NODE) {
translateElement(child);
}
else if(child.nodeType === Node.ELEMENT_NODE) {
if(child.tagName === "INPUT") {
translateElement(child);
} else {
traverseElement(child);
}
} else {
// pass
}
}
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
function watchUpdate() {
const m = window.MutationObserver || window.WebKitMutationObserver;
const observer = new m(function (mutations, observer) {
for(let mutationRecord of mutations) {
for(let node of mutationRecord.addedNodes) {
traverseElement(node);
}
}
});
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
observer.observe(document.body, {
subtree: true,
characterData: true,
childList: true,
});
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
// translate "about"
function translateDesc() {
$(".repository-content .f4").append("<br/>");
$(".repository-content .f4").append("<a id='translate-me' href='#' style='color:rgb(27, 149, 224);font-size: small'>翻译</a>");
$("#translate-me").click(function() {
// get description text
const desc = $(".repository-content .f4")
.clone()
.children()
.remove()
.end()
.text()
.trim();
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
if(!desc) {
return;
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
GM_xmlhttpRequest({
onload: function(res) {
if (res.status === 200) {
$("#translate-me").hide();
// render result
const text = res.responseText;
$(".repository-content .f4").append("<span style='font-size: small'>TK翻译</span>");
$(".repository-content .f4").append("<br/>");
$(".repository-content .f4").append(text);
} else {
alert("翻译失败");
}
}
});
});
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
function translateByCssSelector() {
if(locales.css) {
for(var css of locales.css) {
if($(css.selector).length > 0) {
if(css.key === '!html') {
$(css.selector).html(css.replacement);
} else {
$(css.selector).attr(css.key, css.replacement);
}
}
}
}
}
2023-01-28 01:22:18 +08:00
2022-07-29 12:17:04 +08:00
})();
2023-01-28 01:22:18 +08:00
}