Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6ef29ee

Browse files
feat: add two translate buttons
1 parent 8a5fac8 commit 6ef29ee

File tree

4 files changed

+200
-87
lines changed

4 files changed

+200
-87
lines changed

‎apps/tampermonkey/.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ tampermonkey.js
3131
*.njsproj
3232
*.sln
3333
*.sw?
34+
35+
src/nextjs.html

‎apps/tampermonkey/dist/script.iife.js‎

Lines changed: 75 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// @name Next.js i18n Tampermonkey Script
33
// @namespace https://github.com/xiaoyu2er/nextjs-i18n-docs
44
// @website https://github.com/xiaoyu2er/nextjs-i18n-docs
5-
// @version 0.0.1
5+
// @version 0.0.2
66
// @updateURL https://raw.githubusercontent.com/xiaoyu2er/nextjs-i18n-docs/refs/heads/dev/apps/tampermonkey/dist/script.iife.js
77
// @downloadURL https://raw.githubusercontent.com/xiaoyu2er/nextjs-i18n-docs/refs/heads/dev/apps/tampermonkey/dist/script.iife.js
88
// @description Adds a translation button to nextjs.org with links to community-maintained translated documentation
@@ -115,22 +115,21 @@
115115
);
116116
function devLog(...args) {
117117
}
118-
function devWarn(...args) {
119-
}
120-
function devError(...args) {
121-
}
122-
function waitForLearnButton(callback, maxAttempts = 30) {
118+
function waitForTargetButton(callback, maxAttempts = 30) {
123119
let attempts = 0;
124120
const check = () => {
125121
try {
126122
const learnButton = document.querySelector('a[href="/learn"]');
127-
if (learnButton) {
123+
const searchButton = document.querySelector('button[aria-label="Search documentation"]');
124+
if (learnButton || searchButton) {
128125
callback();
129-
} else if (attempts < maxAttempts) {
126+
return;
127+
}
128+
if (attempts < maxAttempts) {
130129
attempts++;
131130
setTimeout(check, 200);
132131
} else {
133-
devLog("⚠️ Learn button not found after maximum attempts");
132+
devLog("⚠️ Neither Learn button nor Search button found after maximum attempts");
134133
}
135134
} catch (error) {
136135
}
@@ -298,6 +297,8 @@
298297
return container;
299298
}
300299
function addTranslationButton() {
300+
var _a, _b;
301+
let addedCount = 0;
301302
const learnButtonSelectors = [
302303
'a[href="/learn"]',
303304
'a[href*="/learn"]',
@@ -311,57 +312,89 @@
311312
break;
312313
}
313314
}
314-
if (!learnButton) {
315-
return;
316-
}
317-
try {
318-
const existingButton = document.querySelector(
319-
".next-i18n-translate-container"
320-
);
321-
if (existingButton) {
322-
devLog("✅ Translation button already exists");
323-
return;
315+
if (learnButton) {
316+
const existingLearnButton = (_a = learnButton.parentNode) == null ? void 0 : _a.querySelector(".next-i18n-translate-container");
317+
if (!existingLearnButton) {
318+
try {
319+
const translationDropdown = createTranslationDropdown();
320+
translationDropdown.setAttribute("data-placement", "learn-button");
321+
const parentNode = learnButton.parentNode;
322+
if (parentNode) {
323+
if (learnButton.nextSibling) {
324+
parentNode.insertBefore(translationDropdown, learnButton.nextSibling);
325+
} else {
326+
parentNode.appendChild(translationDropdown);
327+
}
328+
devLog("✅ Translation button added next to Learn button");
329+
addedCount++;
330+
}
331+
} catch (error) {
332+
}
324333
}
325-
const translationDropdown = createTranslationDropdown();
326-
const parentNode = learnButton.parentNode;
327-
if (!parentNode) {
328-
devError("❌ Learn button has no parent node");
329-
return;
334+
}
335+
const searchButtonSelectors = [
336+
'button[aria-label="Search documentation"]',
337+
"button.navbar_search__dZT2b",
338+
'button[data-variant="small"]'
339+
];
340+
let searchButton = null;
341+
for (const selector of searchButtonSelectors) {
342+
try {
343+
searchButton = document.querySelector(selector);
344+
if (searchButton) {
345+
devLog(`🔍 Found Search button with selector: ${selector}`);
346+
break;
347+
}
348+
} catch (error) {
330349
}
331-
if (learnButton.nextSibling) {
332-
parentNode.insertBefore(translationDropdown, learnButton.nextSibling);
333-
} else {
334-
parentNode.appendChild(translationDropdown);
350+
}
351+
if (searchButton) {
352+
const existingSearchButton = (_b = searchButton.parentNode) == null ? void 0 : _b.querySelector(".next-i18n-translate-container");
353+
if (!existingSearchButton) {
354+
try {
355+
const translationDropdown = createTranslationDropdown();
356+
translationDropdown.setAttribute("data-placement", "search-button");
357+
const parentNode = searchButton.parentNode;
358+
if (parentNode) {
359+
if (searchButton.nextSibling) {
360+
parentNode.insertBefore(translationDropdown, searchButton.nextSibling);
361+
} else {
362+
parentNode.appendChild(translationDropdown);
363+
}
364+
devLog("✅ Translation button added next to Search button");
365+
addedCount++;
366+
}
367+
} catch (error) {
368+
}
335369
}
336-
devLog("✅ Translation button added successfully");
370+
}
371+
if (addedCount === 0 && !learnButton && !searchButton) {
372+
return false;
373+
}
374+
if (addedCount > 0) {
337375
setTimeout(() => {
338-
const verifyButton = document.querySelector(
376+
const verifyButtons = document.querySelectorAll(
339377
".next-i18n-translate-container"
340378
);
341-
if (!verifyButton) {
342-
devWarn(
343-
"⚠️ Translation button was removed shortly after adding, React might be re-rendering"
344-
);
379+
if (verifyButtons.length === 0) {
345380
setTimeout(() => {
346-
devLog(
347-
"🔄 Attempting to re-add translation button after React stabilization"
348-
);
349381
addTranslationButton();
350382
}, 1e3);
351383
} else {
352-
devLog("🎉 Translation button is stable and working!");
384+
devLog(`🎉 ${verifyButtons.length} translation button(s) are stable and working!`);
353385
}
354386
}, 500);
355-
} catch (error) {
356387
}
388+
return addedCount > 0;
357389
}
358390
function initializeScript() {
359391
setTimeout(() => {
360392
addTranslationButton();
361393
setTimeout(() => {
362-
if (!document.querySelector(".next-i18n-translate-container")) {
363-
waitForLearnButton(() => {
364-
devLog("🎯 Learn button found, attempting to add translation button");
394+
const existingButtons = document.querySelectorAll(".next-i18n-translate-container");
395+
if (existingButtons.length === 0) {
396+
waitForTargetButton(() => {
397+
devLog("🎯 Target button found, attempting to add translation button");
365398
addTranslationButton();
366399
});
367400
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /