Re: 工欲善其事,必先利其器:準備更新哈哈倉頡
发表于 : 2026年 5月 21日 13:22
修正:
當點擊一個詞A,再點擊另一個詞B,如果詞A是在詞B的後面,則詞A將移至詞B的前面(這部分現在是對的),如果詞A是在詞B的前面,則詞A將移至詞B的後面(這部分現在不對)。
當移動結束,應該取消高亮,也就是去掉「selected」。
當一個edit-row中的項目,跟原來original的項目一致時,它的背景應呈淺綠色,Orig前要加上「=」。
把Reset edit change 跟close放到下一行,並在左邊增加undo和redo。
當加詞確認後,輸入框和確認按鈕都不會消失,可以再次輸入和增加。
只需給出所要修改的地方,所有的代碼和注釋都要使用英文。
gemini pro就是要這種複雜一點的:
當點擊一個詞A,再點擊另一個詞B,如果詞A是在詞B的後面,則詞A將移至詞B的前面(這部分現在是對的),如果詞A是在詞B的前面,則詞A將移至詞B的後面(這部分現在不對)。
當移動結束,應該取消高亮,也就是去掉「selected」。
當一個edit-row中的項目,跟原來original的項目一致時,它的背景應呈淺綠色,Orig前要加上「=」。
把Reset edit change 跟close放到下一行,並在左邊增加undo和redo。
當加詞確認後,輸入框和確認按鈕都不會消失,可以再次輸入和增加。
只需給出所要修改的地方,所有的代碼和注釋都要使用英文。
gemini pro就是要這種複雜一點的:
代码: 全选
Here are the necessary modifications to implement all requested features (movement logic, background color for identical rows, UI button layout, undo/redo functionality, and input box persistence).
### 1. Update the HTML Buttons Layout
Locate the `.edit-actions` div in the HTML section and split it into two rows, adding the Undo and Redo buttons.
**Find:**
```html
<div class="edit-actions">
<button id="btnMoveEnd" class="edit-action-btn" onclick="handleEditAction('end')">Put to the end</button>
<button id="btnDelete" class="edit-action-btn" onclick="handleEditAction('delete')">Delete</button>
<button id="btnResetEdit" class="edit-action-btn" onclick="handleEditResetOnly()">Reset Edit Changes</button>
<button id="btnCloseEdit" class="edit-action-btn" onclick="handleEditCloseOnly()">Close</button>
</div>
```
**Replace with:**
```html
<div class="edit-actions">
<button id="btnMoveEnd" class="edit-action-btn" onclick="handleEditAction('end')">Put to the end</button>
<button id="btnDelete" class="edit-action-btn" onclick="handleEditAction('delete')">Delete</button>
</div>
<div class="edit-actions" style="margin-top: 10px;">
<button id="btnUndo" class="edit-action-btn" onclick="handleUndo()">Undo</button>
<button id="btnRedo" class="edit-action-btn" onclick="handleRedo()">Redo</button>
<button id="btnResetEdit" class="edit-action-btn" onclick="handleEditResetOnly()">Reset Edit Changes</button>
<button id="btnCloseEdit" class="edit-action-btn" onclick="handleEditCloseOnly()">Close</button>
</div>
```
---
### 2. Add Global Undo/Redo State Functions
Locate the global variable declarations (around `let originalSnapshotState = new Map();`) and insert the history stacks and functions right below them.
**Find:**
```javascript
let pendingAction = null;
let originalSnapshotState = new Map();
// Setup Event Listeners
```
**Replace with:**
```javascript
let pendingAction = null;
let originalSnapshotState = new Map();
let undoStack = [];
let redoStack = [];
function saveStateForUndo() {
let currentLines = mcc0string.split('\n').filter(l => l.trim() !== '');
undoStack.push(currentLines);
redoStack = []; // Clear redo stack whenever a new action occurs
}
function handleUndo() {
if (undoStack.length === 0) return;
let currentLines = mcc0string.split('\n').filter(l => l.trim() !== '');
redoStack.push(currentLines);
let prevState = undoStack.pop();
let oldState = getSystemState();
processContent(JSON.stringify(prevState));
detectAndRenderChanges(oldState, getSystemState());
}
function handleRedo() {
if (redoStack.length === 0) return;
let currentLines = mcc0string.split('\n').filter(l => l.trim() !== '');
undoStack.push(currentLines);
let nextState = redoStack.pop();
let oldState = getSystemState();
processContent(JSON.stringify(nextState));
detectAndRenderChanges(oldState, getSystemState());
}
// Setup Event Listeners
```
---
### 3. Keep Input Box Visible and Save State on Add
Modify `handleEditSubmit` to keep the input box from disappearing, lock the baseline only once per session, and save the state if a new word is added.
**Find:**
```javascript
if (!lines.includes(val)) {
lines.push(val);
processContent(JSON.stringify(lines));
}
let code = 'z';
```
**Replace with:**
```javascript
if (!lines.includes(val)) {
saveStateForUndo(); // Save state before adding new word
lines.push(val);
processContent(JSON.stringify(lines));
}
let code = 'z';
```
**Find (further down in `handleEditSubmit`):**
```javascript
// CRITICAL FIX: Lock unchanged baseline structural footprint before user interaction
originalSnapshotState = getSystemState();
document.getElementById('inputArea').style.display = 'none';
document.getElementById('editArea').style.display = 'block';
renderEditArea();
```
**Replace with:**
```javascript
// CRITICAL FIX: Lock unchanged baseline structural footprint only once per session
if (!originalSnapshotState || originalSnapshotState.size === 0) {
originalSnapshotState = getSystemState();
}
// Keep input area visible allowing repeated inputs
document.getElementById('inputArea').style.display = 'block';
document.getElementById('editArea').style.display = 'block';
renderEditArea();
```
---
### 4. Update Movement Logic and Clear Highlight
Modify `handleItemClick` to correctly place Word A before Word B if it was originally after, or after Word B if it was originally before, and finally save state.
**Find:**
```javascript
if (idxA > -1) {
let oldState = getSystemState();
// Extract A from lines
lines.splice(idxA, 1);
// Recalculate target position index for element B
let idxB = lines.indexOf(word);
if (idxB > -1) {
// ALWAYS place word A directly in front of word B
lines.splice(idxB, 0, selectedEditItem);
processContent(JSON.stringify(lines));
let newState = getSystemState();
detectAndRenderChanges(oldState, newState);
}
}
selectedEditItem = null;
```
**Replace with:**
```javascript
let originalIdxA = idxA;
let originalIdxB = lines.indexOf(word);
if (originalIdxA > -1 && originalIdxB > -1 && originalIdxA !== originalIdxB) {
let oldState = getSystemState();
saveStateForUndo(); // Save state before movement
// Extract A from lines
lines.splice(originalIdxA, 1);
// Recalculate target position index for element B after A is removed
let newIdxB = lines.indexOf(word);
// If A was originally after B, move A to be before B
if (originalIdxA > originalIdxB) {
lines.splice(newIdxB, 0, selectedEditItem);
}
// If A was originally before B, move A to be after B
else {
lines.splice(newIdxB + 1, 0, selectedEditItem);
}
processContent(JSON.stringify(lines));
let newState = getSystemState();
detectAndRenderChanges(oldState, newState);
}
selectedEditItem = null; // Clear highlight after moving
```
---
### 5. Add Background Color and "Orig" Tag Update for Identical Rows
Modify `renderEditArea` to detect if the current line entirely matches the baseline.
**Find:**
```javascript
if (activeItems.length > 0 || originalItems.length > 0) {
// Render active editable line elements
let activeRowDiv = document.createElement('div');
activeRowDiv.className = 'edit-row';
let activeTitle = document.createElement('div');
```
**Replace with:**
```javascript
if (activeItems.length > 0 || originalItems.length > 0) {
// Check if active items perfectly match original baseline items
let isIdentical = false;
let activeWordsArr = activeItems.map(i => i.w);
if (activeWordsArr.length === originalItems.length && activeWordsArr.every((v, i) => v === originalItems[i])) {
isIdentical = true;
}
// Render active editable line elements
let activeRowDiv = document.createElement('div');
activeRowDiv.className = 'edit-row';
// Apply light green background if the row exactly matches the original
if (isIdentical && originalItems.length > 0) {
activeRowDiv.style.backgroundColor = '#e8f5e9';
}
let activeTitle = document.createElement('div');
```
**Find (further down in `renderEditArea`):**
```javascript
// Mobile-Only context insertion rendering logic block
let mobilePreviewDiv = document.createElement('div');
mobilePreviewDiv.className = 'mobile-original-preview';
mobilePreviewDiv.innerHTML = '<strong>Orig: </strong>';
if (originalItems.length === 0) {
```
**Replace with:**
```javascript
// Mobile-Only context insertion rendering logic block
let mobilePreviewDiv = document.createElement('div');
mobilePreviewDiv.className = 'mobile-original-preview';
// Add '=' indicator before 'Orig' if identical
if (isIdentical && originalItems.length > 0) {
mobilePreviewDiv.innerHTML = '<strong>= Orig: </strong>';
} else {
mobilePreviewDiv.innerHTML = '<strong>Orig: </strong>';
}
if (originalItems.length === 0) {
```
---
### 6. Save State on Delete/Put to End & Reset History Stacks
Ensure state is saved when deleting or moving to the end, and history resets when closing.
**Find in `applyActionToWord`:**
```javascript
let oldState = getSystemState();
if (action === 'delete') {
```
**Replace with:**
```javascript
let oldState = getSystemState();
saveStateForUndo(); // Save state before executing delete or put-to-end action
if (action === 'delete') {
```
**Find in `handleEditCloseOnly`:**
```javascript
originalSnapshotState.clear();
updateActionButtonsUI();
```
**Replace with:**
```javascript
originalSnapshotState.clear();
undoStack = []; // Reset history
redoStack = []; // Reset history
updateActionButtonsUI();
```
**Find in `handleEditResetOnly`:**
```javascript
changedWords.clear();
selectedEditItem = null;
pendingAction = null;
updateActionButtonsUI();
```
**Replace with:**
```javascript
changedWords.clear();
selectedEditItem = null;
pendingAction = null;
undoStack = []; // Reset history after hard revert
redoStack = []; // Reset history
updateActionButtonsUI();
```