update firefox

This commit is contained in:
C 2023-10-10 14:25:32 +08:00
parent 7de69b958b
commit 6c6cbf428a
8 changed files with 450 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,151 @@
let dataVersion = null
chrome.runtime.onInstalled.addListener(function () {
_checkVersion().then(_ => { });
console.log("SWTT init");
});
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action === "_loadLocalizationData") {
_initLocalization(request.url).then(data => {
sendResponse({ result: data });
});
return true;
}
});
async function _checkVersion() {
dataVersion = await _getJsonData("versions.json");
console.log("Localization Version ===");
console.log(dataVersion);
}
async function _initLocalization(url) {
console.log("url ===" + url);
if (dataVersion == null) {
await _checkVersion();
return _initLocalization(url);
}
let v = dataVersion
// TODO check version
let data = {};
data["zh-CN"] = await _getJsonData("zh-CN-rsi.json", { cacheKey: "zh-CN", version: v.rsi });
if (url.includes("robertsspaceindustries.com")) {
data["concierge"] = await _getJsonData("concierge.json", { cacheKey: "concierge", version: v.concierge });
data["orgs"] = await _getJsonData("orgs.json", v.orgs);
data["address"] = await _getJsonData("addresses.json", { cacheKey: "orgs", version: v.addresses });
data["hangar"] = await _getJsonData("hangar.json", { cacheKey: "hangar", version: v.hangar });
} else {
data["UEX"] = await _getJsonData("zh-CN-uex.json", { cacheKey: "uex", version: v.uex });
}
// update data
let replaceWords = getLocalizationResource(data, "zh-CN");
function addLocalizationResource(key) {
replaceWords.push(...getLocalizationResource(data, key));
}
if (url.includes("robertsspaceindustries.com")) {
const org = "https://robertsspaceindustries.com/orgs";
const citizens = "https://robertsspaceindustries.com/citizens";
const organization = "https://robertsspaceindustries.com/account/organization";
const concierge = "https://robertsspaceindustries.com/account/concierge";
const referral = "https://robertsspaceindustries.com/account/referral-program";
const address = "https://robertsspaceindustries.com/account/addresses";
const hangar = "https://robertsspaceindustries.com/account/pledges";
if (url.startsWith(org) || url.startsWith(citizens) || url.startsWith(organization)) {
replaceWords.push({ "word": 'members', "replacement": '名成员' });
addLocalizationResource("orgs");
}
if (url.startsWith(address)) {
addLocalizationResource("address");
}
if (url.startsWith(referral)) {
replaceWords.push(
{ "word": 'Total recruits: ', "replacement": '总邀请数:' },
{ "word": 'Prospects ', "replacement": '未完成的邀请' },
{ "word": 'Recruits', "replacement": '已完成的邀请' }
);
}
if (url.startsWith(concierge)) {
addLocalizationResource("concierge");
}
if (url.startsWith(hangar)) {
addLocalizationResource("hangar");
}
} else {
addLocalizationResource("UEX");
}
return replaceWords;
}
function getLocalizationResource(localizationResource, key) {
const localizations = [];
const dict = localizationResource[key];
if (typeof dict === "object") {
for (const [k, v] of Object.entries(dict)) {
const trimmedKey = k
.toString()
.trim()
.toLowerCase()
.replace(/\xa0/g, ' ')
.replace(/\s{2,}/g, ' ');
localizations.push({ "word": trimmedKey, "replacement": v.toString() });
}
}
return localizations;
}
async function _getJsonData(fileName, { cacheKey = "", version = null } = {}) {
url = "https://ch.citizenwiki.cn/json-files/locales/" + fileName;
const box = await getLocalStorage();
if (cacheKey && cacheKey !== "") {
const localVersion = await getLocalData(`${cacheKey}_version`);
const data = await getLocalData(cacheKey);
if (data && typeof data === 'object' && Object.keys(data).length > 0 && localVersion === version) {
return data;
}
}
const startTime = new Date();
const response = await fetch(url, { method: 'GET', mode: 'cors' });
const endTime = new Date();
const data = await response.json();
if (cacheKey && cacheKey !== "") {
console.log(`update ${cacheKey} v == ${version} time == ${(endTime - startTime) / 1000}s`);
await setLocalData(cacheKey, data);
await setLocalData(`${cacheKey}_version`, version);
}
return data;
}
function getLocalStorage() {
return new Promise((resolve) => {
chrome.storage.local;
resolve();
});
}
function getLocalData(key) {
return new Promise((resolve) => {
chrome.storage.local.get([key], (result) => {
const data = result[key];
resolve(data || null);
});
});
}
function setLocalData(key, data) {
return new Promise((resolve) => {
const newData = {};
newData[key] = data;
chrome.storage.local.set(newData, () => {
resolve();
});
});
}

View File

@ -0,0 +1,149 @@
let replaceLocalesMap = {};
function InitWebLocalization() {
// init script
LocalizationWatchUpdate();
// load Data
_loadLocalizationData();
}
function LocalizationWatchUpdate() {
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);
}
}
});
observer.observe(document.body, {
subtree: true,
characterData: true,
childList: true,
});
if (window.location.hostname.includes("www.erkul.games") || window.location.hostname.includes("ccugame.app")) {
document.body.addEventListener("click", function (event) {
setTimeout(function () {
allTranslate().then(_ => {
});
}, 200);
});
}
}
function WebLocalizationUpdateReplaceWords(w) {
let replaceWords = w.sort(function (a, b) {
return b.word.length - a.word.length;
});
replaceWords.forEach(({ word, replacement }) => {
replaceLocalesMap[word] = replacement;
});
allTranslate().then(_ => {
});
// console.log("WebLocalizationUpdateReplaceWords ==" + w)
}
async function allTranslate() {
async function replaceTextNode(node1) {
if (node1.nodeType === Node.TEXT_NODE) {
let nodeValue = node1.nodeValue;
const key = nodeValue.trim().toLowerCase()
.replace(/\xa0/g, ' ') // replace ' '
.replace(/\s{2,}/g, ' ');
if (replaceLocalesMap[key]) {
nodeValue = replaceLocalesMap[key]
}
node1.nodeValue = nodeValue;
} else {
for (let i = 0; i < node1.childNodes.length; i++) {
await replaceTextNode(node1.childNodes[i]);
}
}
}
await replaceTextNode(document.body);
}
function traverseElement(el) {
if (!shouldTranslateEl(el)) {
return
}
for (const child of el.childNodes) {
if (["RELATIVE-TIME", "TIME-AGO"].includes(el.tagName)) {
translateRelativeTimeEl(el);
return;
}
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
}
}
}
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';
}
const txtSrc = el[k].trim();
const key = txtSrc.toLowerCase()
.replace(/\xa0/g, ' ') // replace '&nbsp;'
.replace(/\s{2,}/g, ' ');
if (replaceLocalesMap[key]) {
el[k] = el[k].replace(txtSrc, replaceLocalesMap[key])
}
}
function translateRelativeTimeEl(el) {
const lang = (navigator.language || navigator.userLanguage);
const datetime = $(el).attr('datetime');
$(el).text(timeago.format(datetime, lang.replace('-', '_')));
}
function shouldTranslateEl(el) {
const blockIds = [];
const blockClass = [
"css-truncate" // 过滤文件目录
];
const blockTags = ["IMG", "svg", "mat-icon"];
if (blockTags.includes(el.tagName)) {
return false;
}
if (el.id && blockIds.includes(el.id)) {
return false;
}
if (el.classList) {
for (let clazz of blockClass) {
if (el.classList.contains(clazz)) {
return false;
}
}
}
return true;
}
InitWebLocalization();
function _loadLocalizationData() {
chrome.runtime.sendMessage({ action: "_loadLocalizationData", url: window.location.href }, function (response) {
WebLocalizationUpdateReplaceWords(response.result);
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -0,0 +1,47 @@
{
"manifest_version": 2,
"name": "星际公民盒子浏览器拓展",
"version": "0.0.1",
"description": "为星际公民网站及工具站提供汉化",
"author": "xkeyC",
"icons": {
"128": "icon.png"
},
"permissions": [
"storage",
"https://ch.citizenwiki.cn/*"
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"background": {
"scripts": [
"background.js"
]
},
"content_scripts": [
{
"matches": [
"https://robertsspaceindustries.com/*",
"https://*.robertsspaceindustries.com/*",
"https://www.erkul.games/*",
"https://uexcorp.space/*",
"https://ccugame.app/*"
],
"js": [
"core.js",
"thirdparty/timeago.full.min.js"
]
},
{
"matches": [
"https://www.erkul.games/*",
"https://ccugame.app/*"
],
"js": [
"thirdparty/jquery.min.js"
]
}
]
}

View File

@ -0,0 +1,100 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>星际公民盒子浏览器拓展</title>
<style>
body {
background-color: black;
}
.card {
border-radius: 8px;
background-color: rgba(255, 255, 255, 0.3);
padding: 10px;
margin: 10px;
width: 250px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
color: black;
}
.card img,
.card svg {
height: 60px;
width: 60px;
}
.card a {
text-decoration: none;
color: #ffffff;
}
.card h3,
.card p {
margin: 5px 0;
/* 上下间距为5px左右间距为0 */
}
.card a:hover {
text-decoration: underline;
}
</style>
</style>
</head>
<body>
<div class="card" style="padding-top: 0; padding-bottom: 0; border-radius: 0;">
<a href="https://github.com/xkeyC/StarCitizenBoxBrowserEx" target="_blank">
<div>
<h2>星际公民盒子浏览器拓展</h2>
</div>
</a>
</div>
<div class="card">
<a href="https://robertsspaceindustries.com/" target="_blank">
<svg viewBox="0 0 56 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M16.0716 0C17.111 0 17.7697 0.734004 17.5824 1.65153L17.5516 1.77773L16.4646 5.68023C16.2499 6.48564 15.6763 7.15995 14.9845 7.52983L14.8228 7.6097L11.6546 9.08403L12.3485 11.8374C12.4102 12.0494 12.6179 12.227 12.8583 12.2638L12.9497 12.2708H15.0308L14.0135 16H10.7299C9.96799 16 9.22678 15.4621 8.98803 14.8024L8.94926 14.6774L7.95482 10.8185L5.17986 12.1191L4.11629 16H0L4.34743 0H16.0716ZM30.028 0L30.0255 0.00849999L29.0084 3.71374L29.0048 3.72704H29.0004L22.8229 3.71374C22.4538 3.71374 22.1768 3.84407 22.0843 4.19052C22.0024 4.49868 22.1027 4.73832 22.3854 4.94011L22.4999 5.01406L29.1008 9.10927C29.7285 9.49516 30.0921 10.3574 29.9828 11.0527L29.9546 11.1894L29.0084 14.6781C28.8348 15.3511 28.0883 15.9282 27.3084 15.9938L27.1619 16H18.8519L19.8686 12.2728H24.8772C25.2464 12.2728 25.5232 12.0346 25.5925 11.8178C25.6756 11.5644 25.6278 11.3636 25.3483 11.1522L25.2464 11.0812L18.5995 6.92095C17.9719 6.53476 17.6081 5.67281 17.7173 4.97743L17.7455 4.84076L18.6914 1.33023C18.8654 0.657352 19.5912 0.0802618 20.3495 0.0146972L20.492 0.00849999L30.0218 0H30.028ZM34.8758 0L39.0028 0.00849999L34.6207 16H30.4473L34.8566 0.00849999H34.8735L34.8758 0ZM17.698 12.2956L16.6916 16H16.0205L17.0206 12.2956H17.698ZM16.356 12.2956L15.313 16H14.5946L15.6471 12.3028L15.6493 12.2956H16.356ZM19.124 12.2956L18.0887 16H17.3625L18.398 12.2956H19.124ZM12.2017 3.70443H7.46927L6.45853 7.48768L12.0409 4.81988C12.5006 4.60106 12.6614 4.33872 12.7304 4.12006C12.8222 3.83596 12.5694 3.70443 12.2017 3.70443ZM34.1379 0L33.1305 3.70443H32.4604L33.474 0H34.1379ZM32.712 0L31.7062 3.70443H31.0345L32.0511 0H32.712ZM31.3537 0L31.3515 0.00844828H31.37L30.3313 3.69121L30.3277 3.70443H29.6086L29.6121 3.69121L30.6322 0.00844828L30.6346 0H31.3537Z"
fill="currentColor"></path>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M44.0993 0.5C45.1052 0.5 45.71 0.718656 46.0714 1.07635C46.4317 1.43287 46.6502 2.02678 46.6502 3.01365C46.6502 4.00008 46.4317 4.58521 46.0739 4.93447C45.7133 5.28641 45.1085 5.5 44.0993 5.5C43.0905 5.5 42.4701 5.28657 42.0962 4.9303C41.7277 4.57908 41.5 3.99382 41.5 3.01365C41.5 2.03297 41.7277 1.43898 42.0987 1.08055C42.4734 0.718531 43.0938 0.5 44.0993 0.5ZM47.1502 3.01365C47.1502 0.918004 46.2283 0 44.0993 0C41.9703 0 41 0.918004 41 3.01365C41 5.10816 41.9703 6 44.0993 6C46.2283 6 47.1502 5.10816 47.1502 3.01365ZM42.7675 1.363C43.2445 1.318 43.717 1.3 44.194 1.3C45.157 1.3 45.4855 1.633 45.4855 2.5105C45.4855 3.154 45.319 3.4555 44.842 3.577L45.607 4.7965C45.643 4.846 45.6205 4.8865 45.553 4.8865H44.725C44.6215 4.8865 44.59 4.855 44.545 4.7875L43.816 3.6355H43.645V4.8145C43.645 4.873 43.6315 4.8865 43.5775 4.8865H42.7675C42.7135 4.8865 42.7 4.873 42.7 4.8145V1.4215C42.7 1.381 42.7135 1.3675 42.7675 1.363ZM44.527 2.542C44.527 2.2495 44.428 2.1235 44.0905 2.1235H43.645V2.9425H44.0905C44.428 2.9425 44.527 2.839 44.527 2.542Z"
fill="currentColor"></path>
</svg>
<h3>星际公民官网</h3>
<p>罗伯茨航天工业公司,万物的起源</p>
</a>
</div>
<div class="card">
<a href="https://uexcorp.space" target="_blank">
<img src="https://uexcorp.space/img/uex-logo-v1.svg" alt="">
<h3>UEX</h3>
<p>采矿、精炼、贸易计算器、价格、船信息</p>
</a>
</div>
<div class="card">
<a href="https://www.erkul.games/live/calculator" target="_blank">
<img src="https://www.erkul.games/assets/icons/icon-512x512.png">
<h3>DPS 计算器</h3>
<p>在线改船,查询伤害数值和配件购买地点</p>
</a>
</div>
<div class="card">
<a href="https://ccugame.app" target="_blank">
<img src="https://ccugame.app/assets/images/logo/logo.png">
<h3>CCUGame</h3>
<p>资产管理和舰队规划,一定要理性消费.jpg</p>
</a>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long