Files
github-zh-tw/DEVELOPMENT.md

7.1 KiB
Raw Permalink Blame History

GitHub 中文化 (繁體) UserScript — 開發紀錄

一份給 ScriptCat / Tampermonkey 用的 GitHub 介面繁體中文化腳本,檔案在 github-zh-tw.user.js。本文件紀錄從 v0.6 一路迭代到 v0.15 的過程、遇到的坑與解法。

設計原則

  1. 只翻 GitHub 介面本身,不動使用者內容。 檔名、commit 訊息、issue 標題、使用者名稱、topic 標籤、repo 描述、README、程式碼一律保留原樣。
  2. 不破壞功能。 搜尋語法(is:issue state:open)必須維持英文,否則點擊篩選會失效。
  3. SPA 友善。 GitHub 用 Turbo/pushState切頁不會重載腳本需要自己監聽。
  4. 效能優先。 預編譯 regex、debounce、只處理必要節點。

架構概念

三層替換:

text
 ├─ TIME_AGO_REGEX           "3 days ago"  → "3 天前"
 ├─ WORD_BOUNDARY_REGEX      詞庫批次替換(長詞優先、大小寫不敏感)
 └─ ABBREV_REGEX             "62.8k"       → "6.3 萬"

兩層跳過:

shouldSkipTextAncestor(el)
 ├─ SKIP_TAGS                SCRIPT / STYLE / CODE / PRE / INPUT / TEXTAREA ...
 ├─ isContentEditable / role="textbox"
 └─ SKIP_CONTEXT_SELECTOR    closest() 快速判斷使用者內容脈絡

掃描策略:TreeWalker 走所有文字節點 + querySelectorAll(ATTR_SELECTOR) 補翻屬性。

版本演進

v0.6(初版)

使用者提供,基本能翻導覽列。用 setInterval(500ms) 輪詢 + MutationObserver flag。

問題: 詞庫太少、每個詞跑一次 regex 效能差、沒處理 SPA。

v0.7

  • 擴充詞庫Settings、Pulls、Commits、Branches…
  • 使用預編譯的 WORD_BOUNDARY_REGEX 一次替換
  • 拿掉 setInterval 輪詢,改 MutationObserver + debounce
  • Hook pushState / replaceState、監聽 turbo:load

v0.8

Bug stars / watching / forks 小寫沒被翻。 原因: regex 只有 gi 旗標。 修:gi,搭配 LOWER_MAP 做大小寫不敏感查表。

Bug Security and quality安全 and quality原因: 只有 Security 在詞庫,and quality 不在。 修: 加整句 Security and quality安全與品質。長詞優先排序會先吃掉整句。

v0.9(數字格式化)

使用者要求「62.8k」改成更好看的格式。

新增 formatAbbrev

  • ≥ 1 萬X.X 萬≥100 萬去掉小數)
  • < 1 萬 → 千分號 7,800
  • 純數字不動

額外問題: <strong>62.8k</strong> 沒被掃到。 原因: SCAN_SELECTORS 沒包 <strong>修: 加入 strong, b, em, h1-h4, li

v0.10

Bug 按鈕上的 7.8k / 62.8k(在 <span class="Counter"> 裡)沒格式化。 原因: Counter 在 skip 清單。 修: 移除 Counter skip。純數字本來就不會被誤翻k/M 後綴才會處理。

v0.11(分支頁)

Branches 頁大量詞彙沒翻Default、Active、Stale、All、Updated、Check status、Behind、Ahead 等。

也加了相對時間 regex

TIME_AGO_REGEX = /\b(\d+)\s+(second|minute|hour|day|week|month|year)s?\s+ago\b/gi

Active 分支清單 的半翻:Branches分支(中文無複數差異),加整句 Active branches活躍分支

v0.12TreeWalker 重構)

Bug <th> / <td> / <relative-time> 的文字沒翻,<input> 的 placeholder 也沒翻。 原因: SCAN_SELECTORS 白名單太窄;<input> 整個被 SKIP_TAGS 跳過,連屬性都沒碰。

大改:

  1. 拿掉 SCAN_SELECTORS改用 TreeWalker 走所有文字節點
  2. 屬性翻譯獨立於文字節點跳過邏輯 — <input> 文字跳過但 placeholder 仍翻
  3. shouldSkipTextAncestor 改成走 parent chain比單一元素判斷更穩

v0.13

補空狀態整句:No branches match the search沒有分支符合搜尋條件 等。

教訓: 差點加了 of/共,但 of 會破壞「Member of X」「out of」等句型移除。同理 PageShowing 也太通用不加。

v0.14(使用者內容保護)

使用者抱怨檔名、commit 訊息、repo 描述被翻(授權 / 自述檔.md / 更新.sh / Initial 提交 / 全部 IN ONE Hacking Tool For Hackers)。

新增 SKIP_CONTEXT_SELECTOR

  • 檔名:.react-directory-filename-columna[href*="/blob/"]a[href*="/tree/"]
  • Commita[href*="/commit/"][data-testid="latest-commit-details"]
  • Repo 描述:.BorderGrid-cell > p.f4.my-3
  • Topicsa.topic-tag
  • README.markdown-body
  • 程式碼:.blob-code-inner.highlight.react-code-lines
  • Issue / PR 標題:.markdown-title.js-issue-title

el.closest(SKIP_CONTEXT_SELECTOR) 一次判斷祖先脈絡。

v0.15Issues 頁)

多個新問題:

  1. is:issue state:開啟中 — 搜尋語法被翻,破壞功能
  2. karanraza608-星標 — 使用者名稱被翻
  3. 下拉選單沒翻Sort by / Newest / Oldest…
  4. read the 貢獻 guidelines — 半翻
  5. Dismiss / Want to contribute 沒翻

新增跳過脈絡:

  • 使用者:a[data-hovercard-type="user"|"organization"]a[data-hovercard-url*="/users/"]
  • 搜尋:[role="searchbox"][role="combobox"]、語法 token .pl-c1
  • Labels.IssueLabel.Label

新增詞庫: Sort by / Order / Newest / Oldest / Created on / Last updated / Total comments / Best match / Reactions / Recently updated / Dismiss / Want to contribute to / 整句 If you have a bug or an idea, read the contributing guidelines before opening an issue

關鍵技術點

大小寫不敏感 + 保留原大小寫?

做不到。因為 Open (tab) 和 opened (issue meta 動詞) 經過 gi + LOWER_MAP 會用同一個翻譯。只能二選一。目前選「保留 tab 翻譯」,動詞保留英文。

長詞優先

const sorted = [...TRANSLATION_MAP.keys()]
  .sort((a, b) => b.length - a.length)

搭配 regex 的回溯backtracking長詞失敗時會嘗試短詞。讓「Active branches」整句優先於「Branches」單字。

屬性裡的 ... 結尾

Search branches... 放進詞庫但 \b...\b 的尾端 \b 不會成立(. 是非字元 + 後方結尾也非字元)。解法是詞庫只放 Search branchesregex 會在 \b 前停下,保留後面的 ...

React 元件的 key 變動

GitHub 的 React class 常含 hashSearchInput-module__searchInput_f5Xpk)。不靠這些,改靠穩定的 roledata-testiddata-hovercard-*[href*="/blob/"]

目前已知限制

  • 大小寫衝突:同詞不同語境無法分別翻譯。
  • 使用者自定 label / project 名稱:會看內容決定,但已用 .IssueLabel / .Label 跳過彩色 label。
  • Issue 標題:刻意保留英文(屬使用者內容)。
  • 新 UI 改版:如果 GitHub 改變 class / data-testid跳過規則可能失效。

檔案

  • github-zh-tw.user.js — 腳本本體
  • DEVELOPMENT.md — 本文件

安裝

在 ScriptCat / Tampermonkey「新增腳本」貼上 github-zh-tw.user.js 全文。或用「從本地檔案匯入」。