|
1 | 1 | // Inject a language toggle button into the topbar (sphinx-book-theme compatible) |
2 | 2 | (function(){ |
3 | 3 | const STORAGE_KEY = 'slime-doc-lang'; |
4 | | - const AVAILABLE = ['en','zh']; |
| 4 | + // Default language EN has no URL prefix; Chinese uses '/zh/' inserted after optional repo root. |
5 | 5 | function detectCurrent(){ |
6 | | - const { parts, langIndex } = analyzePath(); |
7 | | - if(langIndex !== -1) return parts[langIndex]; |
8 | | - return 'en'; |
| 6 | + const { zhIndex } = analyzePath(); |
| 7 | + return zhIndex !== -1 ? 'zh' : 'en'; |
9 | 8 | } |
10 | | - function otherLang(lang){ return lang === 'en' ? 'zh' : 'en'; } |
| 9 | + function otherLang(lang){ return lang === 'zh' ? 'en' : 'zh'; } |
11 | 10 | /** |
12 | 11 | * Analyze current pathname to figure out repo root + language segment pattern. |
13 | 12 | * Supports patterns: |
|
18 | 17 | */ |
19 | 18 | function analyzePath(){ |
20 | 19 | const rawParts = window.location.pathname.split('/').filter(Boolean); |
21 | | - let parts = rawParts.slice(); |
| 20 | + const parts = rawParts.slice(); |
22 | 21 | let repoRoot = null; |
23 | | - let langIndex = -1; |
24 | | - |
25 | | - if(parts[0] && AVAILABLE.includes(parts[0])){ |
26 | | - langIndex = 0; // /en/... |
27 | | - } else if(parts.length > 1 && AVAILABLE.includes(parts[1])){ |
| 22 | + if(parts.length > 0 && (window.location.host.endsWith('github.io') || parts[0] === 'slime')){ |
28 | 23 | repoRoot = parts[0]; |
29 | | - langIndex = 1; // /slime/en/... |
30 | | - } else { |
31 | | - // No explicit language; try to detect repo root (GitHub Pages typical) so we insert AFTER it. |
32 | | - // Heuristic: if host ends with github.io OR first segment matches known repo name 'slime'. |
33 | | - if(parts.length > 0 && (window.location.host.endsWith('github.io') || parts[0] === 'slime')){ |
34 | | - repoRoot = parts[0]; |
35 | | - } |
36 | 24 | } |
37 | | - return { parts, repoRoot, langIndex }; |
| 25 | + let zhIndex = -1; |
| 26 | + if(parts[0] === 'zh') zhIndex = 0; else if(parts[1] === 'zh') zhIndex = 1; |
| 27 | + return { parts, repoRoot, zhIndex }; |
38 | 28 | } |
39 | 29 |
|
40 | 30 | function buildTargetUrl(target){ |
41 | 31 | const url = new URL(window.location.href); |
42 | 32 | const trailingSlash = url.pathname.endsWith('/') || url.pathname === '/'; |
43 | | - const { parts, repoRoot, langIndex } = analyzePath(); |
44 | | - |
45 | | - if(langIndex === 0){ |
46 | | - // replace first |
47 | | - parts[0] = target; |
48 | | - } else if(langIndex === 1){ |
49 | | - parts[1] = target; // replace second (/repo/en/) |
50 | | - } else if(repoRoot){ |
51 | | - // insert after repo root |
52 | | - if(parts.length === 1){ |
53 | | - parts.push(target); // /repo/ -> /repo/zh/ |
54 | | - } else { |
55 | | - parts.splice(1, 0, target); |
| 33 | + const { parts, repoRoot, zhIndex } = analyzePath(); |
| 34 | + if(target === 'zh'){ |
| 35 | + if(zhIndex === -1){ |
| 36 | + if(repoRoot){ |
| 37 | + if(parts.length === 1) parts.push('zh'); else parts.splice(1,0,'zh'); |
| 38 | + } else { |
| 39 | + parts.unshift('zh'); |
| 40 | + } |
56 | 41 | } |
57 | | - } else { |
58 | | - // no repo root detected; put language first |
59 | | - parts.unshift(target); |
| 42 | + } else { // target en => remove zh if present |
| 43 | + if(zhIndex !== -1) parts.splice(zhIndex,1); |
60 | 44 | } |
61 | | - |
62 | 45 | let newPath = '/' + parts.join('/'); |
63 | | - // Add trailing slash if original had it and new path doesn't look like a file (no extension) |
64 | | - if(trailingSlash && !/\.[a-zA-Z0-9]+$/.test(parts[parts.length-1] || '')) newPath += '/'; |
| 46 | + if(newPath === '/') { |
| 47 | + // stay root |
| 48 | + } else if(trailingSlash && !/\.[a-zA-Z0-9]+$/.test(parts[parts.length-1] || '')) newPath += '/'; |
65 | 49 | url.pathname = newPath; |
66 | 50 | return url.toString(); |
67 | 51 | } |
|
0 commit comments