Skip to content
Merged
12 changes: 6 additions & 6 deletions CLAUDE.md

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@
- 完整伺服器/職業選擇

### 宗長計算機 (`faux-hollows-foxes/`)
- Faux Hollows Foxes 活動的 6x6 棋盤策略工具
- 自動填充障礙物
- 252 種盤面機率計算
- 三段式寶物機率顯示
- Faux Hollows Foxes 活動的 6x6 盤面(252 種盤面資料);盤面上方的狀態列寫現在要做什麼、還能翻幾次:① 點遊戲裡被擋住的格子 → ② 找劍 → ③ 找寶箱 → ④ 翻宗長(不一定有)→ 完成,剩的次數不夠翻完劍或寶箱時直接跳到下一個目標;下一格框綠色,一樣好的全部框
- 標障礙物時,候選格顯示障礙物機率,不可能是障礙物的格子點不了;其他障礙物的位置能確定時自動補上(斜線加虛線框,拿掉手動標的它補上的跟著消失),擺法只剩一種就進入翻格
- 還沒翻的格子寫劍、寶箱的機率(例如 ⚔️75%、📦13%,0 不寫);宗長只放 🦊,意思是「宗長有出現的話,可能在這格」,不寫數字(宗長出現的機率沒有公開,拿盤面的比例當機率會每翻開一個空格就往上加,最後變成 100%),找到宗長之後其他格就不再放 🦊
- 翻開一格後點它,在格子旁邊的小選單選劍、寶箱、宗長或空(上三列開在下方、下三列開在上方):和其他格對不上的選項是灰的,只剩一種可能時點一下就標好;點標好的格子可以改選或清除,翻了好幾格之後回頭改,機率、🦊、下一格都跟著重算
- 候選依劍藍、寶箱紅、宗長黃等分底色;「隱藏機率」只隱藏百分比數字,圖示、候選底色與建議綠框都保留
- 「上一步」會寫出退回了什麼,「重做」恢復退回的動作;「重置遊戲」另放一行,清空盤面後仍能用上一步救回來。格子都是按鈕,可以用鍵盤操作,格子的名稱也會把提示唸給螢幕閱讀器

### 寶圖搜尋器 (`treasure-map-finder/`)
- 真實寶圖座標資料庫(227個座標)
Expand Down Expand Up @@ -193,9 +195,8 @@ ff14.tw/
│ │ ├── common.js # 共用函式庫(含漢堡選單、FF14Utils)
│ │ ├── security-utils.js # 安全工具(XSS 防護)
│ │ ├── modal-manager.js # 對話框管理
│ │ ├── state-history-manager.js # 狀態歷史管理
│ │ ├── reminder-scheduler.js # 提醒排程(頁內提示、提示音、系統通知;天氣預報與特殊採集時間管理器的「提醒我」使用)
│ │ ├── cell-popover.js # 格子旁的小選單(不是對話框;仙人微彩使用)
│ │ ├── cell-popover.js # 格子旁的小選單(不是對話框;仙人微彩、宗長計算機使用)
│ │ ├── home.js # 首頁腳本(最近使用)
│ │ ├── not-found.js # 404 頁腳本(工具清單)
│ │ ├── components/ # 動態載入元件
Expand All @@ -219,14 +220,15 @@ ff14.tw/
│ ├── add-design-links.mjs
│ ├── remove-dark-mode-links.mjs
│ └── replace-noscript-nav.mjs
├── tests/ # 50 份 node --test 測試(下列為部分範例)
├── tests/ # 52 份 node --test 測試(下列為部分範例)
│ ├── design-system.test.js
│ ├── docs.test.js
│ ├── gathering-materials.test.js
│ ├── gathering-reminders.test.js
│ ├── helpers/ # 測試輔助模組(不是測試檔)
│ │ ├── cactpot-page.js # 仙人微彩頁的頁面替身
│ │ ├── gathering-page.js # 採集頁的頁面替身
│ │ ├── hollows-page.js # 宗長計算機頁的頁面替身
│ │ ├── notification-stubs.js # Notification/AudioContext 替身
│ │ └── wondrous-page.js # 天書奇談頁的頁面替身
│ ├── modal-manager-stack.test.js
Expand Down
2 changes: 1 addition & 1 deletion assets/css/tools-common.css
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@
opacity: 0.7;
}

/* 建議(綠色):仙人推薦的格子與線、之後宗長的下一格;放在 :hover、:disabled 後面,兩種狀態下都維持綠色 */
/* 建議(綠色):仙人推薦的格子與線、宗長的下一格;放在 :hover、:disabled 後面,兩種狀態下都維持綠色 */
.cell.suggested {
border: 2px solid var(--color-success);
background: var(--color-success-tint);
Expand Down
266 changes: 100 additions & 166 deletions assets/js/i18n/translations/tools/faux-hollows-foxes.js

Large diffs are not rendered by default.

176 changes: 0 additions & 176 deletions assets/js/state-history-manager.js

This file was deleted.

21 changes: 21 additions & 0 deletions changelog.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@ <h1 data-i18n="changelog_hero_title">修改紀錄</h1>
<section class="changelog-section">
<h2 class="changelog-year">2026年10月</h2>

<article class="changelog-entry">
<div class="changelog-header">
<h3 class="changelog-version">v2.26.0</h3>
<time class="changelog-date" datetime="2026-10-27">2026年10月27日</time>
</div>
<div class="changelog-content">
<ul>
<li><span class="tag tag-success">新增</span> 宗長計算機盤面上方多了一行狀態列,直接寫現在要做什麼、還能翻幾次:① 點遊戲裡被擋住的格子 → ② 找劍 → ③ 找寶箱 → ④ 翻宗長(不一定有)→ 完成。剩的次數不夠翻完劍或寶箱時,會直接跳到下一個目標。下一個該翻的格子用綠色框出來,有好幾個一樣好的就全部框起來</li>
<li><span class="tag tag-info">改善</span> 在遊戲裡翻開一格後,點這一格,旁邊會跳出小選單,選劍、寶箱、宗長或空(以前是蓋住整個盤面的視窗)。和其他格對不上的選項是灰的,只剩一種可能時點一下就標好;點標好的格子可以改選或清除,翻了好幾格之後回頭改,機率和建議也會跟著重算</li>
<li><span class="tag tag-info">改善</span> 標障礙物時,候選格顯示障礙物機率,不可能是障礙物的格子變淡、不能點;能確定的障礙物會自動補上,用斜線加虛線框,和你自己標的分得出來。拿掉你標的障礙物,它補上的也會跟著消失;障礙物的位置全部確定後自動進入翻格,障礙物鎖住,要改請按「上一步」</li>
<li><span class="tag tag-info">改善</span> 每個還沒翻的格子直接寫劍、寶箱的機率(例如「⚔️75%」「📦13%」),機率是 0 的不寫;宗長只放 🦊,意思是「宗長有出現的話,可能在這格」,不寫數字(宗長多常出現沒有公開,算不出真正的機率);找到宗長之後,其他格就不再放 🦊。用螢幕閱讀器時,格子的名稱也會唸出這些提示和「建議翻這格」</li>
<li><span class="tag tag-info">改善</span> 劍、寶箱、宗長的候選提示保留藍、紅、黃底色;一種候選填滿一格、兩種各半、三種各佔三分之一。「隱藏機率」只隱藏百分比數字,圖示、底色和建議綠框都保留</li>
<li><span class="tag tag-info">改善</span> 「上一步」會寫出退回了什麼(例如「已退回:第 26 格標成劍」),「重做」可恢復退回的動作;「重置遊戲」另放一行,按下去清空盤面開始新的一局,按錯了按「上一步」可以救回來,也能重做重置</li>
<li><span class="tag tag-info">改善</span> 格子都是按鈕,可以用鍵盤操作:Enter 標障礙物或打開小選單,小選單用鍵盤打開時焦點直接在第一個能選的選項,Esc 關掉。焦點所在的格子鎖住時(例如標完障礙物進入翻格),焦點會自動移到下一格,不會掉到頁面上</li>
<li><span class="tag tag-info">改善</span> 拿掉「關閉最佳策略」、最後的分數卡(遊戲裡會自己顯示拿到什麼)、「符合盤面」那一欄和說明段落,頁面上保留狀態列、機率開關、盤面、上一步/重做/重置遊戲,和盤面下面一句 🦊 的說明與資料來源</li>
<li><span class="tag tag-warning">修正</span> 以前標錯障礙物或寶物時,盤面會變成一片空白、沒有任何訊息;現在不可能的格子和選項都點不了</li>
<li><span class="tag tag-warning">修正</span> 以前「最佳策略」會同時亮好幾格,分不出先翻哪一格;現在照「先找劍、再找寶箱、最後翻宗長」的順序,把下一格框出來</li>
</ul>
</div>
</article>

<article class="changelog-entry">
<div class="changelog-header">
<h3 class="changelog-version">v2.25.0</h3>
Expand Down
20 changes: 8 additions & 12 deletions tests/design-system.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -349,18 +349,7 @@ test('.btn-close/.popup-close/.btn-remove 按鈕必須有可存取名稱(a
assert.ok(jsChecked > 0, '沒有找到任何 JS 動態建立的 CLOSE_CLASSES 中的按鈕,測試可能失效');
});

test('猜謎方格工具的格子都能用 Tab 鍵移動焦點(div 要設 tabindex,按鈕本來就可以)', () => {
const jsChecks = [
{ file: 'tools/faux-hollows-foxes/script.js', classNamePattern: /cell\.className\s*=\s*'cell board-cell'/ }
];
for (const { file, classNamePattern } of jsChecks) {
const js = read(file);
const match = classNamePattern.exec(js);
assert.ok(match, `${file} 找不到格子的 className 設定,測試可能失效`);
const windowText = js.slice(match.index, match.index + 300);
assert.match(windowText, /\.tabIndex\s*=\s*0|setAttribute\(\s*['"]tabindex['"]/, `${file} 的格子工廠沒有設定 tabindex`);
}

test('猜謎方格工具(仙人微彩、天書奇談、宗長計算機)的格子都是按鈕,都能用 Tab 鍵移動焦點', () => {
const html = read('tools/mini-cactpot/index.html');
const gridCells = html.match(/<button type="button" class="cell grid-cell"[^>]*>/g) || [];
assert.equal(gridCells.length, 9, 'mini-cactpot 應該有 9 個 .grid-cell 按鈕');
Expand All @@ -374,6 +363,13 @@ test('猜謎方格工具的格子都能用 Tab 鍵移動焦點(div 要設 tabi
for (const tag of wondrousCells) {
assert.doesNotMatch(tag, /\stabindex="-1"/, `wondrous-tails 的格子不應該移出 Tab 順序:${tag}`);
}

const hollowsHtml = read('tools/faux-hollows-foxes/index.html');
const hollowsCells = hollowsHtml.match(/<button type="button" class="cell grid-cell"[^>]*>/g) || [];
assert.equal(hollowsCells.length, 36, 'faux-hollows-foxes 應該有 36 個 .grid-cell 按鈕');
for (const tag of hollowsCells) {
assert.doesNotMatch(tag, /\stabindex="-1"/, `faux-hollows-foxes 的格子不應該移出 Tab 順序:${tag}`);
}
});

test('每個 role="tablist" 都至少有一個帶 aria-selected 的 role="tab"', () => {
Expand Down
Loading
Loading