Skip to content

Commit fe2432f

Browse files
committed
feat: 添加首页和测试用例列表页的专用国际化脚本
1 parent 97aa1a2 commit fe2432f

File tree

2 files changed

+347
-0
lines changed

2 files changed

+347
-0
lines changed

js/i18n/i18n-cases.js

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
class I18nCases {
2+
constructor(i18n) {
3+
this.i18n = i18n;
4+
}
5+
6+
update() {
7+
// 检查是否在测试用例列表页面
8+
const casesPageHeader = document.querySelector('.cases-container .section-header');
9+
if (!casesPageHeader) return;
10+
11+
// 更新页面标题
12+
document.title = this.i18n.t('casesPage.title');
13+
14+
// 更新测试用例badge
15+
const casesPageBadge = document.querySelector('.cases-container .section-badge');
16+
if (casesPageBadge) {
17+
const iconElement = casesPageBadge.querySelector('i');
18+
casesPageBadge.innerHTML = '';
19+
if (iconElement) casesPageBadge.appendChild(iconElement);
20+
casesPageBadge.appendChild(document.createTextNode(' ' + this.i18n.t('casesPage.badge')));
21+
}
22+
23+
// 更新测试用例标题和描述
24+
const casesPageTitle = document.querySelector('.cases-container .section-header h2');
25+
if (casesPageTitle) casesPageTitle.textContent = this.i18n.t('casesPage.heading');
26+
27+
const casesPageDesc = document.querySelector('.cases-container .section-header p');
28+
if (casesPageDesc) casesPageDesc.textContent = this.i18n.t('casesPage.description');
29+
30+
// 更新类别标题 - 改进选择器和匹配方式
31+
const categoryHeaders = document.querySelectorAll('.case-category h2');
32+
if (categoryHeaders && categoryHeaders.length > 0) {
33+
// 遍历所有类别标题
34+
categoryHeaders.forEach(header => {
35+
const headerText = header.textContent.trim();
36+
const icon = header.querySelector('i');
37+
38+
// 基础执行模式
39+
if (headerText.includes('基础执行') || headerText.includes('Basic Execution')) {
40+
this.updateCategoryHeader(header, icon, this.i18n.t('casesPage.categories.basic'));
41+
}
42+
// 定时器模式
43+
else if (headerText.includes('定时器') || headerText.includes('Timer')) {
44+
this.updateCategoryHeader(header, icon, this.i18n.t('casesPage.categories.timer'));
45+
}
46+
// 构造函数模式
47+
else if (headerText.includes('构造函数') || headerText.includes('Constructor')) {
48+
this.updateCategoryHeader(header, icon, this.i18n.t('casesPage.categories.constructor'));
49+
}
50+
// 在线网站测试
51+
else if (headerText.includes('在线网站') || headerText.includes('Online Site')) {
52+
this.updateCategoryHeader(header, icon, this.i18n.t('casesPage.categories.online'));
53+
}
54+
// 工具网站测试
55+
else if (headerText.includes('工具网站') || headerText.includes('Tool Site')) {
56+
this.updateCategoryHeader(header, icon, this.i18n.t('casesPage.categories.tools'));
57+
}
58+
// 其他模式
59+
else if (headerText.includes('其他') || headerText.includes('Other')) {
60+
this.updateCategoryHeader(header, icon, this.i18n.t('casesPage.categories.other'));
61+
}
62+
});
63+
}
64+
65+
// 更新贡献区域
66+
const contributeTitle = document.querySelector('.contribute-section h3');
67+
if (contributeTitle) contributeTitle.textContent = this.i18n.t('casesPage.contribute.title');
68+
69+
const contributeDesc = document.querySelector('.contribute-section p');
70+
if (contributeDesc) contributeDesc.textContent = this.i18n.t('casesPage.contribute.description');
71+
72+
const newCaseBtn = document.querySelector('.contribute-buttons a:nth-child(1)');
73+
if (newCaseBtn) {
74+
const icon = newCaseBtn.querySelector('i');
75+
newCaseBtn.innerHTML = '';
76+
if (icon) newCaseBtn.appendChild(icon);
77+
newCaseBtn.appendChild(document.createTextNode(' ' + this.i18n.t('casesPage.contribute.newCase')));
78+
}
79+
80+
const submitPRBtn = document.querySelector('.contribute-buttons a:nth-child(2)');
81+
if (submitPRBtn) {
82+
const icon = submitPRBtn.querySelector('i');
83+
submitPRBtn.innerHTML = '';
84+
if (icon) submitPRBtn.appendChild(icon);
85+
submitPRBtn.appendChild(document.createTextNode(' ' + this.i18n.t('casesPage.contribute.submitPR')));
86+
}
87+
88+
// 更新测试用例列表中的内容
89+
this.updateTestCaseItems();
90+
}
91+
92+
// 辅助方法:更新类别标题
93+
updateCategoryHeader(header, icon, text) {
94+
header.innerHTML = '';
95+
if (icon) header.appendChild(icon);
96+
header.appendChild(document.createTextNode(' ' + text));
97+
}
98+
99+
// 更新测试用例内容
100+
updateTestCaseItems() {
101+
// 获取所有测试用例项
102+
const caseItems = document.querySelectorAll('.case-item');
103+
if (!caseItems || caseItems.length === 0) return;
104+
105+
// 为每个测试用例项更新名称和描述
106+
caseItems.forEach(item => {
107+
const caseName = item.querySelector('.case-name');
108+
const caseDesc = item.querySelector('.case-description');
109+
const caseBadge = item.querySelector('.case-badge');
110+
111+
// 根据当前测试用例的文本内容确定其类型,并设置相应的翻译
112+
if (caseName) {
113+
const nameText = caseName.textContent.trim();
114+
115+
// 处理eval执行测试用例
116+
if (nameText.includes('eval') || nameText.includes('Eval')) {
117+
caseName.textContent = this.i18n.currentLang === 'zh-CN' ? 'eval 执行' : 'eval Execution';
118+
if (caseDesc) {
119+
caseDesc.textContent = this.i18n.currentLang === 'zh-CN'
120+
? '使用 eval 函数执行 debugger 语句'
121+
: 'Execute debugger statement using eval function';
122+
}
123+
}
124+
// 处理Function构造函数测试用例
125+
else if (nameText.includes('Function') || nameText.includes('构造函数')) {
126+
caseName.textContent = this.i18n.currentLang === 'zh-CN' ? 'Function 构造函数' : 'Function Constructor';
127+
if (caseDesc) {
128+
caseDesc.textContent = this.i18n.currentLang === 'zh-CN'
129+
? '使用 Function 构造函数执行 debugger 语句'
130+
: 'Execute debugger statement using Function constructor';
131+
}
132+
}
133+
// 处理setInterval基础测试用例
134+
else if (nameText.includes('setInterval') && nameText.includes('基础')) {
135+
caseName.textContent = this.i18n.currentLang === 'zh-CN' ? 'setInterval 基础' : 'Basic setInterval';
136+
if (caseDesc) {
137+
caseDesc.textContent = this.i18n.currentLang === 'zh-CN'
138+
? '使用 setInterval 循环执行 debugger 语句'
139+
: 'Execute debugger statement in a loop using setInterval';
140+
}
141+
}
142+
// 处理setInterval高级测试用例
143+
else if (nameText.includes('setInterval') && nameText.includes('高级')) {
144+
caseName.textContent = this.i18n.currentLang === 'zh-CN' ? 'setInterval 高级' : 'Advanced setInterval';
145+
if (caseDesc) {
146+
caseDesc.textContent = this.i18n.currentLang === 'zh-CN'
147+
? '使用 setInterval 的高级变体执行 debugger 语句'
148+
: 'Execute debugger statement using advanced variants of setInterval';
149+
}
150+
}
151+
// 处理数组构造函数测试用例
152+
else if (nameText.includes('数组') || nameText.toLowerCase().includes('array')) {
153+
caseName.textContent = this.i18n.currentLang === 'zh-CN' ? '数组构造函数' : 'Array Constructor';
154+
if (caseDesc) {
155+
caseDesc.textContent = this.i18n.currentLang === 'zh-CN'
156+
? '使用数组的构造函数链执行 debugger 语句'
157+
: 'Execute debugger statement using array constructor chain';
158+
}
159+
}
160+
// 处理对象构造函数测试用例
161+
else if (nameText.includes('对象') || nameText.toLowerCase().includes('object')) {
162+
caseName.textContent = this.i18n.currentLang === 'zh-CN' ? '对象构造函数' : 'Object Constructor';
163+
if (caseDesc) {
164+
caseDesc.textContent = this.i18n.currentLang === 'zh-CN'
165+
? '使用对象的构造函数执行 debugger 语句'
166+
: 'Execute debugger statement using object constructor';
167+
}
168+
}
169+
// 处理JSON.CN测试用例
170+
else if (nameText.includes('JSON.CN')) {
171+
caseName.textContent = 'JSON.CN';
172+
if (caseDesc) {
173+
caseDesc.textContent = this.i18n.currentLang === 'zh-CN'
174+
? 'JSON.CN 网站的调试检测绕过测试'
175+
: 'Debugger detection bypass test for JSON.CN website';
176+
}
177+
}
178+
// 处理JavaScript混淆工具测试用例
179+
else if (nameText.includes('混淆') || nameText.toLowerCase().includes('obfuscator')) {
180+
caseName.textContent = this.i18n.currentLang === 'zh-CN' ? 'JavaScript 混淆工具' : 'JavaScript Obfuscator Tool';
181+
if (caseDesc) {
182+
caseDesc.textContent = this.i18n.currentLang === 'zh-CN'
183+
? 'JavaScript 混淆工具网站的调试检测绕过测试'
184+
: 'Debugger detection bypass test for JavaScript Obfuscator Tool website';
185+
}
186+
}
187+
// 处理其他测试用例
188+
else if (nameText.includes('其他') || nameText.toLowerCase().includes('other')) {
189+
caseName.textContent = this.i18n.currentLang === 'zh-CN' ? '其他测试用例' : 'Other Test Cases';
190+
if (caseDesc) {
191+
caseDesc.textContent = this.i18n.currentLang === 'zh-CN'
192+
? '其他类型的 debugger 语句执行测试'
193+
: 'Tests for other types of debugger statement execution';
194+
}
195+
}
196+
}
197+
198+
// 更新测试用例徽章 - 改进徽章文本处理
199+
if (caseBadge) {
200+
// 提取徽章内容,去除图标
201+
const iconElement = caseBadge.querySelector('i');
202+
let badgeText = caseBadge.textContent.trim();
203+
204+
// 直接处理所有可能的徽章类型
205+
if (badgeText.includes('基础测试') || badgeText.includes('Basic Test')) {
206+
this.updateBadge(caseBadge, iconElement, this.i18n.currentLang === 'zh-CN' ? '基础测试' : 'Basic Test');
207+
}
208+
else if (badgeText.includes('定时器') || badgeText.includes('Timer')) {
209+
this.updateBadge(caseBadge, iconElement, this.i18n.currentLang === 'zh-CN' ? '定时器' : 'Timer');
210+
}
211+
else if (badgeText.includes('构造函数') || badgeText.includes('Constructor')) {
212+
this.updateBadge(caseBadge, iconElement, this.i18n.currentLang === 'zh-CN' ? '构造函数' : 'Constructor');
213+
}
214+
else if (badgeText.includes('在线网站') || badgeText.includes('Online Site')) {
215+
this.updateBadge(caseBadge, iconElement, this.i18n.currentLang === 'zh-CN' ? '在线网站' : 'Online Site');
216+
}
217+
else if (badgeText.includes('工具网站') || badgeText.includes('Tool Site')) {
218+
this.updateBadge(caseBadge, iconElement, this.i18n.currentLang === 'zh-CN' ? '工具网站' : 'Tool Site');
219+
}
220+
else if (badgeText.includes('其他') || badgeText.includes('Other')) {
221+
this.updateBadge(caseBadge, iconElement, this.i18n.currentLang === 'zh-CN' ? '其他' : 'Other');
222+
}
223+
}
224+
});
225+
}
226+
227+
// 辅助方法:更新徽章内容
228+
updateBadge(badge, icon, text) {
229+
badge.innerHTML = '';
230+
if (icon) badge.appendChild(icon);
231+
badge.appendChild(document.createTextNode(text));
232+
}
233+
}

js/i18n/i18n-home.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
class I18nHome {
2+
constructor(i18n) {
3+
this.i18n = i18n;
4+
}
5+
6+
update() {
7+
// 检查是否在首页
8+
if (!document.querySelector('.hero')) return;
9+
10+
// 更新 hero 部分
11+
const heroBadge = document.querySelector('.hero-badge span');
12+
if (heroBadge) heroBadge.textContent = this.i18n.t('hero.badge');
13+
14+
const heroTitle = document.querySelector('.hero h2');
15+
if (heroTitle) heroTitle.textContent = this.i18n.t('hero.title');
16+
17+
const heroDesc = document.querySelector('.hero p');
18+
if (heroDesc) heroDesc.textContent = this.i18n.t('hero.description');
19+
20+
const startTest = document.querySelector('.hero .cta-buttons .button:first-child');
21+
if (startTest) {
22+
const icon = startTest.querySelector('i');
23+
startTest.innerHTML = '';
24+
if (icon) startTest.appendChild(icon);
25+
startTest.appendChild(document.createTextNode(' ' + this.i18n.t('hero.startTest')));
26+
}
27+
28+
const viewSource = document.querySelector('.hero .cta-buttons .button.outline');
29+
if (viewSource) {
30+
const icon = viewSource.querySelector('i');
31+
viewSource.innerHTML = '';
32+
if (icon) viewSource.appendChild(icon);
33+
viewSource.appendChild(document.createTextNode(' ' + this.i18n.t('hero.viewSource')));
34+
}
35+
36+
// 更新中间CTA部分
37+
const ctaBadgeElement = document.querySelector('.cta .section-badge');
38+
if (ctaBadgeElement) {
39+
// 保存图标元素
40+
const iconElement = ctaBadgeElement.querySelector('i');
41+
// 清空内容
42+
ctaBadgeElement.innerHTML = '';
43+
// 重新添加图标
44+
if (iconElement) ctaBadgeElement.appendChild(iconElement);
45+
// 添加翻译后的文本
46+
ctaBadgeElement.appendChild(document.createTextNode(' ' + this.i18n.t('button.startUsing')));
47+
}
48+
49+
const ctaTitle = document.querySelector('.cta h3');
50+
if (ctaTitle) ctaTitle.textContent = this.i18n.t('cta.title');
51+
52+
const ctaDesc = document.querySelector('.cta .cta-content > p');
53+
if (ctaDesc) ctaDesc.textContent = this.i18n.t('cta.description');
54+
55+
const ctaButton = document.querySelector('.cta .cta-buttons .button');
56+
if (ctaButton) {
57+
const icon = ctaButton.querySelector('i');
58+
ctaButton.innerHTML = '';
59+
if (icon) ctaButton.appendChild(icon);
60+
ctaButton.appendChild(document.createTextNode(' ' + this.i18n.t('cta.startTest')));
61+
}
62+
63+
// 更新工作流程部分
64+
const workflowBadgeElement = document.querySelector('.workflow .section-badge');
65+
if (workflowBadgeElement) {
66+
// 保存图标元素
67+
const iconElement = workflowBadgeElement.querySelector('i');
68+
// 清空内容
69+
workflowBadgeElement.innerHTML = '';
70+
// 重新添加图标
71+
if (iconElement) workflowBadgeElement.appendChild(iconElement);
72+
// 添加翻译后的文本
73+
workflowBadgeElement.appendChild(document.createTextNode(' ' + this.i18n.t('workflow.subtitle')));
74+
}
75+
76+
const workflowTitle = document.querySelector('.workflow .section-badge + h2');
77+
if (workflowTitle) workflowTitle.textContent = this.i18n.t('workflow.title');
78+
79+
const workflowDesc = document.querySelector('.workflow .section-header p');
80+
if (workflowDesc) workflowDesc.textContent = this.i18n.t('workflow.description');
81+
82+
const steps = document.querySelectorAll('.workflow-step');
83+
if (steps.length >= 3) {
84+
steps[0].querySelector('h3').textContent = this.i18n.t('workflow.steps.step1.title');
85+
steps[0].querySelector('p').textContent = this.i18n.t('workflow.steps.step1.description');
86+
steps[1].querySelector('h3').textContent = this.i18n.t('workflow.steps.step2.title');
87+
steps[1].querySelector('p').textContent = this.i18n.t('workflow.steps.step2.description');
88+
steps[2].querySelector('h3').textContent = this.i18n.t('workflow.steps.step3.title');
89+
steps[2].querySelector('p').textContent = this.i18n.t('workflow.steps.step3.description');
90+
}
91+
92+
// 更新加入群组部分
93+
const joinGroupTitle = document.querySelector('.join-group h2');
94+
if (joinGroupTitle) joinGroupTitle.textContent = this.i18n.t('joinGroup.title');
95+
96+
const qrCodes = document.querySelectorAll('.qr-code p');
97+
if (qrCodes.length >= 3) {
98+
qrCodes[0].textContent = this.i18n.t('joinGroup.reverseGroup');
99+
qrCodes[1].textContent = this.i18n.t('joinGroup.wechat');
100+
101+
// 对于第三个 QR 码,我们需要小心处理,因为它包含一个链接
102+
const telegramText = qrCodes[2].childNodes[0];
103+
if (telegramText) {
104+
telegramText.textContent = this.i18n.t('joinGroup.telegram') + ' ';
105+
}
106+
107+
// 更新"点此加入"链接文本
108+
const telegramLink = qrCodes[2].querySelector('a');
109+
if (telegramLink) {
110+
telegramLink.textContent = this.i18n.t('joinGroup.click_to_join');
111+
}
112+
}
113+
}
114+
}

0 commit comments

Comments
 (0)