Skip to content

Commit 6ef29ee

Browse files
committed
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy