Skip to content

Commit 4ad49c9

Browse files
WIP: Tagi10n: new plugin
Signed-off-by: Dee.H.Y <[email protected]>
1 parent f5ff6af commit 4ad49c9

File tree

6 files changed

+38578
-0
lines changed

6 files changed

+38578
-0
lines changed

plugins/Tagi10n/Tagi10n.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// Stash Tag Translation
2+
(async function () {
3+
"use strict";
4+
5+
const { waitForElement, PathElementListener, getConfiguration, baseURL } =
6+
window.csLib;
7+
8+
const defaultConfig = {
9+
defaultLanguage: "zh_CN",
10+
};
11+
12+
async function loadLanguageFile(lang) {
13+
try {
14+
// 修改为请求 JSON 文件
15+
const response = await fetch(
16+
`https://cdn.jsdelivr.net/gh/dongfengweixiao/CommunityScripts@tagi10n1/plugins/Tagi10n/i10n/tag_${lang}.json`
17+
);
18+
// 检查响应状态
19+
if (!response.ok) {
20+
throw new Error(`HTTP error! status: ${response.status}`);
21+
}
22+
// 解析 JSON 数据
23+
const languageMap = await response.json();
24+
return languageMap;
25+
} catch (error) {
26+
console.error(`Failed to load language file tag_${lang}.json`, error);
27+
return {};
28+
}
29+
}
30+
31+
function translateTags(languageMap, xpathArray) {
32+
if (!languageMap) {
33+
console.error("languageMap is undefined or null. Translation skipped.");
34+
return;
35+
}
36+
37+
xpathArray.forEach((xpath) => {
38+
const elements = document.evaluate(
39+
xpath,
40+
document,
41+
null,
42+
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
43+
null
44+
);
45+
for (let i = 0; i < elements.snapshotLength; i++) {
46+
const element = elements.snapshotItem(i);
47+
const originalText = element.textContent.trim();
48+
element.textContent = languageMap[originalText][0];
49+
}
50+
});
51+
}
52+
53+
function translateTagDescriptions(languageMap) {
54+
if (!languageMap) {
55+
console.error(
56+
"languageMap is undefined or null. Description translation skipped."
57+
);
58+
return;
59+
}
60+
61+
const tagNameElements = document.evaluate(
62+
"//div[contains(@class, 'tag-card')]//div[@class='TruncatedText']",
63+
document,
64+
null,
65+
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
66+
null
67+
);
68+
69+
for (let i = 0; i < tagNameElements.snapshotLength; i++) {
70+
const tagNameElement = tagNameElements.snapshotItem(i);
71+
const tagName = tagNameElement.textContent.trim();
72+
73+
const descriptionElement = document.evaluate(
74+
"//div[contains(@class, 'tag-card')]//div[contains(@class, 'tag-description')]",
75+
tagNameElement.parentNode,
76+
null,
77+
XPathResult.FIRST_ORDERED_NODE_TYPE,
78+
null
79+
).singleNodeValue;
80+
81+
const translationEntry = languageMap[tagName];
82+
83+
if (
84+
descriptionElement &&
85+
Array.isArray(translationEntry) &&
86+
translationEntry.length > 1
87+
) {
88+
descriptionElement.textContent = translationEntry[1];
89+
}
90+
}
91+
}
92+
93+
async function main() {
94+
const config = await getConfiguration("Tagi10n", defaultConfig);
95+
const lang = config.defaultLanguage;
96+
const languageMap = await loadLanguageFile(lang);
97+
98+
const xpathArray = [
99+
"//div[contains(@span, 'tag-item')]//div",
100+
"//*[contains(@class, 'tag-item')]//div",
101+
"//div[contains(@class, 'tag-card')]//div[@class='TruncatedText']",
102+
"//*[contains(@class, 'tag-name')]",
103+
"//span[contains(@span, 'tag-item')]//div",
104+
];
105+
106+
PathElementListener(baseURL + "scenes", ".tag-item", () => {
107+
translateTags(languageMap, xpathArray);
108+
});
109+
PathElementListener(baseURL + "tags", ".card-section", () => {
110+
translateTagDescriptions(languageMap);
111+
translateTags(languageMap, xpathArray);
112+
});
113+
PathElementListener(baseURL + "tags/", ".tag-name", () => {
114+
translateTagDescriptions(languageMap);
115+
translateTags(languageMap, xpathArray);
116+
});
117+
PathElementListener(baseURL + "images", ".tag-item", () => {
118+
translateTags(languageMap, xpathArray);
119+
});
120+
PathElementListener(baseURL + "performers", ".tag-item", () => {
121+
translateTags(languageMap, xpathArray);
122+
});
123+
PathElementListener(baseURL + "groups", ".tag-item", () => {
124+
translateTags(languageMap, xpathArray);
125+
});
126+
PathElementListener(baseURL + "galleries", ".tag-item", () => {
127+
translateTags(languageMap, xpathArray);
128+
});
129+
}
130+
131+
main();
132+
})();

plugins/Tagi10n/Tagi10n.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Tagi10n
2+
description: Display tag names in the given language.
3+
version: 0.0.1
4+
ui:
5+
requires:
6+
- CommunityScriptsUILibrary
7+
javascript:
8+
- https://cdn.jsdelivr.net/gh/dongfengweixiao/CommunityScripts@tagi10n1/plugins/Tagi10n/i10n/tag_zh_CN.json
9+
- Tagi10n.js
10+
11+
settings:
12+
defaultLanguage:
13+
displayName: Default Language
14+
description: Default Language
15+
type: STRING

0 commit comments

Comments
 (0)