Skip to content

Commit a551f01

Browse files
authored
Add files via upload
1 parent b2261fa commit a551f01

1 file changed

Lines changed: 51 additions & 91 deletions

File tree

3code_mobile.html

Lines changed: 51 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
1010
<style>
1111
/* ----------------------------------------------------- */
12-
/* 樣式定義 (略,與前版相同) */
12+
/* 樣式定義 */
1313
/* ----------------------------------------------------- */
1414

1515
:root {
@@ -101,8 +101,7 @@
101101
background-color: var(--primary-color);
102102
color: white;
103103
cursor: pointer;
104-
box-shadow: 0 2px 5px rgba
105-
(0, 0, 0, 0.1);
104+
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
106105
transition: background-color 0.2s;
107106
}
108107

@@ -127,7 +126,7 @@
127126
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
128127
margin-bottom: 5px;
129128
padding: 8px;
130-
height: 20vh; /* Reduced from 40vh to 20vh */
129+
height: 20vh;
131130
font-size: 1.5rem;
132131
line-height: 1.6;
133132
white-space: pre-wrap;
@@ -231,7 +230,7 @@
231230
background-color: #e8eaf6;
232231
}
233232

234-
/* ADDED: Toolbar item styles */
233+
/* Toolbar item styles */
235234
#candidate-display span.toolbar-tool {
236235
font-size: 1.2rem;
237236
padding: 5px 15px;
@@ -352,7 +351,7 @@
352351
transform: scaleX(2);
353352
}
354353

355-
/* ADDED: Overlay styles */
354+
/* Overlay styles */
356355
#keyboard-overlay {
357356
position: absolute; /* 定位會被 JS 覆蓋 */
358357
left: 0;
@@ -365,18 +364,16 @@
365364

366365
#keyboard-overlay.emoji button {
367366
box-sizing: border-box;
368-
/* 由於 flexbox 佈局,float: left 被移除 */
369367
text-align: center;
370368
font-size: 1.8rem;
371-
/* ADDED: 使其看起來像獨立的按鍵 */
372369
background-color: var(--key-bg); /* 使用鍵盤背景色 #f9f9f9 */
373370
border: 1px solid var(--border-color); /* 添加邊框 */
374371
border-radius: 6px; /* 圓角 */
375372
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); /* 陰影效果 */
376373
margin: 2px; /* 增加微小間隔,讓按鍵更明顯 */
377374
}
378375

379-
/* ADDED: 點擊時的反白效果 */
376+
/* 點擊時的反白效果 */
380377
#keyboard-overlay.emoji button:active {
381378
background-color: var(--key-active-bg); /* 使用點擊時的顏色 #a0a0a0 */
382379
color: white; /* 讓表情符號更突出 */
@@ -441,7 +438,7 @@
441438
let cursorPosition = 0;
442439
let preferredOffset = -1;
443440

444-
// --- ADDED: 簡繁切換狀態 ---
441+
// --- 簡繁切換狀態 ---
445442
let isSimplifiedMode = false; // 預設為繁體模式
446443

447444
// --- 長按相關狀態 ---
@@ -480,19 +477,24 @@
480477
const KEYCODE_ENTER=0x0d;
481478
const KEYCODE_SPACE=0x20;
482479

483-
// --- ADDED: Cursor and forward delete keycodes ---
480+
// --- Cursor and forward delete keycodes ---
484481
const KEYCODE_HOME=0xff50;
485482
const KEYCODE_LEFT=0xff51;
486483
const KEYCODE_UP=0xff52;
487484
const KEYCODE_RIGHT=0xff53;
488485
const KEYCODE_DOWN=0xff54;
489486
const KEYCODE_DEL_F=0xff;
490487

491-
// --- 簡繁轉換表 (將從 ts.txt 外部檔案載入,若失敗則為空) ---
492-
let TS_MAP = {};
493-
494-
// 移除 FALLBACK_TS_MAP_RAW,完全依賴外部檔案載入。
495-
488+
// --- 簡繁轉換表 (基礎示範用,完整轉換需要更大的字典) ---
489+
const TS_MAP = {
490+
'體': '体', '碼': '码', '說': '说', '這': '这', '個': '个',
491+
'們': '们', '樂': '乐', '風': '风', '開': '开', '對': '对',
492+
'會': '会', '國': '国', '議': '议', '變': '变', '應': '应',
493+
'學': '学', '發': '发', '廠': '厂', '廣': '广', '裡': '里',
494+
'幾': '几', '為': '为', '從': '从', '後': '后', '麵': '面',
495+
'術': '术', '隻': '只', '頭': '头', '話': '话', '裡': '里'
496+
};
497+
496498
/**
497499
* 執行簡體字轉換
498500
*/
@@ -509,7 +511,7 @@
509511
return simplifiedText;
510512
}
511513

512-
// --- 鍵盤配置 (略,與前版相同) ---
514+
// --- 鍵盤配置 ---
513515
var Keyboards = {
514516
english: {
515517
shifted : false,
@@ -607,7 +609,7 @@
607609
}
608610

609611
/**
610-
* 鍵盤渲染函數 (略)
612+
* 鍵盤渲染函數
611613
*/
612614
function drawKeyboard() {
613615
const layout = currentLayout;
@@ -752,6 +754,8 @@
752754
}
753755
}
754756

757+
// --- 浮層處理函數 ---
758+
755759
/**
756760
* 處理表情符號/編輯器的浮層顯示與隱藏
757761
*/
@@ -763,7 +767,8 @@
763767
div.style.display = 'none';
764768
div.innerHTML = '';
765769
delete div.dataset.show;
766-
if (isShowing == show && div.className == type) return;
770+
// 如果是嘗試關閉當前開啟的浮層,則直接返回
771+
if (isShowing == show && div.className == type) return;
767772
}
768773

769774
if (show === false) return;
@@ -886,17 +891,11 @@
886891
overlay("editor", 0);
887892
}
888893

889-
// --- ADDED: 工具列邏輯 ---
894+
// --- 工具列邏輯 ---
890895

891896
function showToolbar() {
892897
candidateDisplay.innerHTML = '';
893898

894-
// 1. 如果浮層開啟 (Emoji/Editor)
895-
if (overlayDiv.dataset.show) {
896-
showToolbar();
897-
return;
898-
}
899-
900899
// **CHANGE: Replaced '🎤' with '簡/繁' toggle**
901900
const toolbarItems = [
902901
{title: isSimplifiedMode ? "简" : "繁", tool:"1"}, // 簡繁切換鍵
@@ -920,16 +919,27 @@
920919
candidateDisplay.appendChild(fragment);
921920
}
922921

922+
/**
923+
* 處理工具列點擊事件 (已修正簡繁切換與浮層衝突)
924+
*/
923925
function handleToolbarClick(target) {
924926
const tool = target.dataset.tool;
927+
const isOverlayActive = !!overlayDiv.dataset.show; // 檢查是否有浮層正在開啟
928+
929+
// **修正**:如果浮層是開啟的,且點擊的是「簡繁切換鍵」(tool 1),則只切換模式並立即返回,不影響浮層狀態
930+
if (isOverlayActive && tool === "1") {
931+
isSimplifiedMode = !isSimplifiedMode;
932+
console.log("TS mode switched while overlay active. Overlay preserved.");
933+
// 這裡不需要 showCandidates,因為浮層開啟時,下方的 candidateDisplay 應該保持清空或顯示工具列
934+
// 但我們不希望它觸發重繪 (showCandidates) 導致浮層閃爍,因此直接 return
935+
return;
936+
}
937+
925938
if (tool === "1") {
926-
// **CHANGE: Simplified/Traditional Mode Toggle**
939+
// Simplified/Traditional Mode Toggle
927940
isSimplifiedMode = !isSimplifiedMode;
928-
showCandidates(); // Redraw toolbar to update "" / "繁" label
941+
showCandidates(); // Redraw toolbar to update "" / "繁" label
929942
console.log("Mode switched to:", isSimplifiedMode ? "Simplified" : "Traditional");
930-
if (Object.keys(TS_MAP).length === 0 && isSimplifiedMode) {
931-
alert("警告:簡繁轉換表 (ts.txt) 尚未載入或內容為空,轉換功能將不會生效。");
932-
}
933943
} else if (tool === "2") {
934944
overlay("emoji", 0);
935945
} else if (tool === "3") {
@@ -945,7 +955,7 @@
945955
}
946956

947957
/**
948-
* 處理長按事件:提交輔助字符 (略)
958+
* 處理長按事件:提交輔助字符
949959
*/
950960
function handleLongPress(keyElement, altChar) {
951961
longPressCommitted = true;
@@ -956,7 +966,7 @@
956966
}
957967

958968
/**
959-
* 處理短按事件:執行編碼或普通字符輸入 (略)
969+
* 處理短按事件:執行編碼或普通字符輸入
960970
*/
961971
function handleShortPress(keyElement) {
962972
preferredOffset = -1;
@@ -1110,7 +1120,7 @@
11101120
}
11111121

11121122
/**
1113-
* 統一的事件綁定函數 (略)
1123+
* 統一的事件綁定函數
11141124
*/
11151125
function bindKeyEvents() {
11161126
document.querySelectorAll('.keyboard-key').forEach(keyElement => {
@@ -1184,7 +1194,7 @@
11841194
}
11851195

11861196
/**
1187-
* 處理單字符輸入 (用於英文/符號模式或 Shift+字母) (略)
1197+
* 處理單字符輸入 (用於英文/符號模式或 Shift+字母)
11881198
*/
11891199
function handleCharInput(char) {
11901200
if (currentLayout.shifted) {
@@ -1198,7 +1208,7 @@
11981208
}
11991209
}
12001210

1201-
// --- 核心輸入法邏輯 (其餘部分略) ---
1211+
// --- 核心輸入法邏輯 ---
12021212

12031213
var currentCode = '';
12041214
var currentCandidates = [];
@@ -1283,7 +1293,7 @@
12831293
* 提交文字 (包含簡繁轉換邏輯)
12841294
*/
12851295
function commitText(textToCommit) {
1286-
// **CHANGE: 在提交前進行簡繁轉換**
1296+
// 在提交前進行簡繁轉換
12871297
const finalCommitText = convertToSimplified(textToCommit);
12881298

12891299
committedText = committedText.slice(0, cursorPosition) + finalCommitText + committedText.slice(cursorPosition);
@@ -1304,57 +1314,6 @@
13041314
resetInputState();
13051315
}
13061316
}
1307-
1308-
/**
1309-
* 解析並載入簡繁轉換表 (ts.txt)
1310-
* 預期檔案格式:繁體字\t簡體字 (一行一個)
1311-
*/
1312-
async function loadTSMap() {
1313-
const fileName = './ts.txt';
1314-
let textToParse = ''; // 預設為空,如果載入失敗則保持為空
1315-
1316-
try {
1317-
const response = await fetch(fileName);
1318-
if (response.ok) {
1319-
const responseText = await response.text();
1320-
// 檢查檔案內容是否有效,如果只有空白或註解,則不使用該內容
1321-
if (responseText.trim().replace(/^#.*$/gm, '').trim().length > 0) {
1322-
textToParse = responseText;
1323-
console.log(`成功載入簡繁轉換表: ${fileName}`);
1324-
} else {
1325-
console.warn(`載入外部簡繁轉換表: ${fileName} 成功,但內容為空或僅包含註解。`);
1326-
}
1327-
} else {
1328-
console.error(`無法載入外部簡繁轉換表 (${response.status}),TS_MAP 將保持為空。`);
1329-
}
1330-
} catch (error) {
1331-
console.error('外部簡繁轉換表讀取錯誤:', error.message, 'TS_MAP 將保持為空。');
1332-
}
1333-
1334-
// 解析內容
1335-
const newTSMap = {};
1336-
if (textToParse.length > 0) {
1337-
const lines = textToParse.trim().split('\n');
1338-
lines.forEach(line => {
1339-
// 忽略註解行
1340-
if (line.startsWith('#') || line.trim() === '') return;
1341-
1342-
// 使用 Tab 或多個空格分隔
1343-
const parts = line.split(/[\t\s]+/);
1344-
1345-
if (parts.length >= 2) {
1346-
const traditionalChar = parts[0].trim();
1347-
const simplifiedChar = parts[1].trim();
1348-
if (traditionalChar.length === 1 && simplifiedChar.length === 1) {
1349-
newTSMap[traditionalChar] = simplifiedChar;
1350-
}
1351-
}
1352-
});
1353-
}
1354-
1355-
TS_MAP = newTSMap;
1356-
console.log(`簡繁轉換表已載入,共 ${Object.keys(TS_MAP).length} 條轉換規則。`);
1357-
}
13581317

13591318
function parseCinData(data) {
13601319
const newCodemap = {};
@@ -1385,6 +1344,7 @@
13851344

13861345
async function loadSecondaryCodemap() {
13871346
const fileName = './3codes2.txt';
1347+
// 這是備用的模擬編碼表 (用於測試,請確保您實際的 3codes2.txt 檔案存在並可讀取)
13881348
let textToParse = `# 這是備用的模擬編碼表 (用於測試)\n測\tqwe\n試\trty\n工\taaa\n夫\tqwe\n這\tqwe\n代\tqwe\n碼\tzxc\n說\tzxc\n裡\tqwe\n個\tzxc\n對\tqwe\n會\trty\n國\taaa\n議\tqwe\n變\tqwe\n應\tqwe\n學\trty\n發\taaa\n廠\tqwe\n廣\tqwe\n裡\tqwe\n幾\tqwe\n為\trty\n從\taaa\n後\tqwe\n麵\tqwe\n術\tqwe\n隻\trty\n頭\taaa\n話\tqwe\n裡\tqwe\n「\t;'\n」\t';\n`;
13891349
let statusMessage = '編碼表載入中...';
13901350

@@ -1394,6 +1354,7 @@
13941354
throw new Error(`無法載入外部檔案 (${response.status})。`);
13951355
}
13961356
const responseText = await response.text();
1357+
// 檢查是否真的讀到了有用的內容,否則使用備用內容
13971358
if (responseText.trim().replace(/^#.*$/gm, '').trim().length > 0) {
13981359
textToParse = responseText;
13991360
}
@@ -1503,7 +1464,7 @@
15031464

15041465
currentCandidates.forEach((candidate, index) => {
15051466
const span = document.createElement('span');
1506-
// **NOTE: 候選字在顯示時不轉換,僅在選字 commitText 時才轉換。**
1467+
// NOTE: 候選字在顯示時不轉換,僅在選字 commitText 時才轉換。
15071468
span.textContent = candidate;
15081469
span.onclick = () => selectCandidate(index);
15091470
candidateDisplay.appendChild(span);
@@ -1528,7 +1489,7 @@
15281489
updateOutputDisplay();
15291490
}
15301491

1531-
// --- 工具列與查碼功能 (略) ---
1492+
// --- 工具列與查碼功能 ---
15321493

15331494
function copyTextToClipboard() {
15341495
const textToCopy = committedText;
@@ -1680,7 +1641,6 @@
16801641
// 頁面啟動
16811642
document.addEventListener('DOMContentLoaded', () => {
16821643
drawKeyboard();
1683-
loadTSMap(); // **重要:完全依賴外部檔案載入**
16841644
loadSecondaryCodemap();
16851645

16861646
textOutput.addEventListener('click', handleTextTap);

0 commit comments

Comments
 (0)