將製作ejcees(中國象棋打譜程式)

分享和讨论Javascript相关的话题
回复
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4987
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 173 次
被圈友点赞: 202 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

ejceesExpSvg不能轉json。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4987
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 173 次
被圈友点赞: 202 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

代码: 全选

(function() {
    const currentHash = window.location.hash;
    if (currentHash) {
        const targetLink = document.querySelector('a.ejcees');
        if (targetLink && targetLink.href) {
            const newUrl = targetLink.href + currentHash;
            window.location.href = newUrl;
        }
    }
})();
改進以上代碼,在加上hash前,要先加上?url=當前地址的encodeUricomponer轉碼。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4987
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 173 次
被圈友点赞: 202 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

gemini fast

代码: 全选

(function() {
    const currentHash = window.location.hash;
    // 獲取當前完整 URL 並進行編碼
    const encodedCurrentUrl = encodeURIComponent(window.location.href);

    if (currentHash) {
        const targetLink = document.querySelector('a.ejcees');
        
        if (targetLink && targetLink.href) {
            let baseUrl = targetLink.href;

            // 判斷原連結是否已經帶有參數,決定用 '?' 還是 '&' 拼接
            const separator = baseUrl.includes('?') ? '&' : '?';
            
            // 拼接順序:原連結 + ?url=當前地址 + #Hash
            const newUrl = `${baseUrl}${separator}url=${encodedCurrentUrl}${currentHash}`;
            
            window.location.href = newUrl;
        }
    }
})();
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4987
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 173 次
被圈友点赞: 202 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

url點第二次會出現中文,而不再編碼。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4987
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 173 次
被圈友点赞: 202 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

當程式boot the app,拿到hash時,順帶也拿到?url=...(如果有),之後把地址欄中?後面的以及#後面的字符都去掉。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4987
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 173 次
被圈友点赞: 202 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

找到程式Boot the app部分,在最下面的地方。有一段代碼是拿到hash,現在順帶也拿到?url=...(如果有),之後把地址欄中?後面的以及#後面的字符都去掉。

只需給出所要修改的地方,所有的代碼和注釋都要使用英文。

代码: 全选

根據您的要求,我找到了位於程式碼最下方的「Boot the app」部分。

您需要修改 `window.addEventListener('DOMContentLoaded', ...)` 回調函數中處理 `window.location.hash` 的邏輯。

以下是修改後的程式碼片段(所有程式碼與註釋均使用英文):

```javascript
        // 1. Resolve initial state from localStorage or URL hash
        const savedState = localStorage.getItem(STORAGE_KEY);
        let initialHistory = null;
        
        // --- Modified Section: Handle URL parameters and Hash ---
        const urlParams = new URLSearchParams(window.location.search);
        if (urlParams.has('url')) {
            baseUrl = decodeURIComponent(urlParams.get('url'));
        }

        if (window.location.hash) {
            const hash = window.location.hash.substring(1);
            if (hash) {
                try {
                    initialHistory = parseUrlHash(hash);
                } catch (e) {
                    console.error("Failed to parse hash:", e);
                }
            }
        }

        // Clean up the address bar: remove everything after '?' and '#'
        if (window.location.search || window.location.hash) {
            const cleanUrl = window.location.protocol + "//" + window.location.host + window.location.pathname;
            window.history.replaceState({}, document.title, cleanUrl);
        }
        // --- End of Modified Section ---

        if (!initialHistory && savedState) {
            // ... (rest of the existing logic to load from savedState)
```

### 修改說明:
1.  **獲取 `?url=`**:使用 `URLSearchParams` 從 `window.location.search` 中提取 `url` 參數並解碼賦值給 `baseUrl`。
2.  **獲取 Hash**:保留原有的邏輯,從 `window.location.hash` 中提取並解析棋局數據。
3.  **清除地址欄**:使用 `window.history.replaceState` 將地址欄重置為僅包含 `protocol`、`host` 和 `pathname` 的路徑,從而去掉所有的查詢參數(`?` 後面)和片段標識符(`#` 後面)。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4987
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 173 次
被圈友点赞: 202 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

附件
ejcees20260406url9997775.7z
(45.58 KiB) 已下载 4 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4987
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 173 次
被圈友点赞: 202 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

改進:

一,當點擊「複製」後,如果處於選取範圍狀態,則該狀態消失。

二,當按下鍵盤的ctrl+c、ctrl+v時,如果不處於「導出文本、編輯評論、編輯局面、導出svg、更改移動和間隔時間」狀態,則它的功能等同於按下btn-pinned-copy和btn-pinned-paste按鈕。

三,為各種按鈕增加快捷鍵功能:

tool-new:ctrl+n
tool-open:ctrl+o
tool-edit:ctrl+e
tool-save:ctrl+s
tool-rotate:ctrl+r
tool-flip:ctrl+f
tool-exp-svg:ctrl+ins

注意僅在它們處於高亮狀態時可用。

只需給出所要修改的地方,所有的代碼和注釋都要使用英文。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4987
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 173 次
被圈友点赞: 202 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

gemini pro 深情鉅獻:

代码: 全选

Here are the modifications to implement the requested features. Please find the specified sections in your code and apply the changes. All code and comments are provided in English.

### 1. Extract Copy and Paste logic into global functions
Locate the `renderNoteUI` function definition (around line `988`). Add the new global `performCopy` and `performPaste` functions **immediately before** it:

```javascript
        // --- Added global functions for copy and paste ---
        function performCopy() {
            let textToCopy = "";
            const fmt = lastExportFormat || 'cn';
            const odd = formatOddStates[fmt] || 0;

            if (fmt === 'cn') {
                textToCopy = odd === 1 ? generateTextWithComment(false) : generateExportText(false);
            } else if (fmt === 'en') {
                textToCopy = odd === 1 ? generateTextWithComment(true) : generateExportText(true);
            } else if (fmt === 'engine') {
                let path = getGamePath();
                let engineText = "position fen " + path.fen;
                let currNode = path;
                if (currNode && currNode.v && currNode.v.length > 0) {
                    engineText += " moves";
                }
                while (currNode && currNode.v && currNode.v.length > 0) {
                    currNode = currNode.v[0];
                    let dc = currNode.lastMove;
                    if (dc) {
                        engineText += " " + String.fromCharCode(97 + dc.startX) + (9 - dc.startY) + String.fromCharCode(97 + dc.endX) + (9 - dc.endY);
                    }
                }

                let goCmdStr = savedGoCommand ? ` ${savedGoCommand}` : "";
                if (odd === 1) {
                    const isRed = currentTurn === 'w';
                    const moves = getAllLegalMoves(isRed, tileMap);
                    const searchMovesStr = moves.map(m => String.fromCharCode(97 + m.startX) + (9 - m.startY) + String.fromCharCode(97 + m.endX) + (9 - m.endY)).join(' ');
                    textToCopy = engineText + `\ngo${goCmdStr}` + (searchMovesStr ? ` searchmoves ${searchMovesStr}` : "") + "\n";
                } else {
                    textToCopy = engineText + `\ngo${goCmdStr}\n`;
                }
            } else if (fmt === 'url') {
                textToCopy = generateUrlHash(odd === 1);
            }

            navigator.clipboard.writeText(textToCopy).then(() => {
                // Clear range mode upon successful copy
                if (isRangeMode) {
                    isRangeMode = false;
                    rangeStart = null;
                    rangeEnd = null;
                    rangeClicks = 0;
                    clearRangeBorders();
                    renderNoteUI();
                }
            }).catch(err => {
                console.error('Copy failed', err);
            });
        }

        function performPaste() {
            navigator.clipboard.readText().then(text => {
                if (text.startsWith('go ')) {
                    savedGoCommand = text.substring(3).trim();
                }
                importExportedText(text);
            }).catch(err => {
                console.error('Paste failed', err);
            });
        }

        // Note UI Renderer
        function renderNoteUI() {
```

### 2. Update `renderNoteUI` to use the global functions
Find the event listener definitions for `btn-pinned-copy` and `btn-pinned-paste` inside `renderNoteUI` (around line `1074`) and replace them with calls to the new functions:

**Replace this block:**
```javascript
                if (isExportPinned) {
                    document.getElementById('btn-pinned-copy').addEventListener('click', () => {
                        let textToCopy = "";
                        const fmt = lastExportFormat || 'cn';
                        const odd = formatOddStates[fmt] || 0;

                        if (fmt === 'cn') {
                            textToCopy = odd === 1 ? generateTextWithComment(false) : generateExportText(false);
                        } else if (fmt === 'en') {
                            textToCopy = odd === 1 ? generateTextWithComment(true) : generateExportText(true);
                        } else if (fmt === 'engine') {
                            let path = getGamePath();
                            let engineText = "position fen " + path.fen;
                            let currNode = path;
                            if (currNode && currNode.v && currNode.v.length > 0) {
                                engineText += " moves";
                            }
                            while (currNode && currNode.v && currNode.v.length > 0) {
                                currNode = currNode.v[0];
                                let dc = currNode.lastMove;
                                if (dc) {
                                    engineText += " " + String.fromCharCode(97 + dc.startX) + (9 - dc.startY) + String.fromCharCode(97 + dc.endX) + (9 - dc.endY);
                                }
                            }

                            let goCmdStr = savedGoCommand ? ` ${savedGoCommand}` : "";
                            if (odd === 1) {
                                const isRed = currentTurn === 'w';
                                const moves = getAllLegalMoves(isRed, tileMap);
                                const searchMovesStr = moves.map(m => String.fromCharCode(97 + m.startX) + (9 - m.startY) + String.fromCharCode(97 + m.endX) + (9 - m.endY)).join(' ');
                                textToCopy = engineText + `\ngo${goCmdStr}` + (searchMovesStr ? ` searchmoves ${searchMovesStr}` : "") + "\n";
                            } else {
                                textToCopy = engineText + `\ngo${goCmdStr}\n`;
                            }
                        } else if (fmt === 'url') {
                            textToCopy = generateUrlHash(odd === 1);
                        }

                        navigator.clipboard.writeText(textToCopy).catch(err => {
                            console.error('Copy failed', err);
                        });
                    });

                    document.getElementById('btn-pinned-paste').addEventListener('click', () => {
                        navigator.clipboard.readText().then(text => {
                            // Capture the 'go' command arguments if it starts with 'go '
                            if (text.startsWith('go ')) {
                                savedGoCommand = text.substring(3).trim();
                            }
                            importExportedText(text);
                        }).catch(err => {
                            console.error('Paste failed', err);
                        });
                    });

                    document.getElementById('btn-unpin').addEventListener('click', () => {
```

**With this:**
```javascript
                if (isExportPinned) {
                    document.getElementById('btn-pinned-copy').addEventListener('click', performCopy);
                    document.getElementById('btn-pinned-paste').addEventListener('click', performPaste);

                    document.getElementById('btn-unpin').addEventListener('click', () => {
```

### 3. Implement keyboard shortcuts in the `keydown` event listener
Find the main keyboard event listener `document.addEventListener('keydown', (e) => {` (around line `1854`). Insert the Ctrl shortcut handlers directly inside the `if (e.ctrlKey) {` block:

**Replace this block:**
```javascript
            if (e.ctrlKey) {
                // Ctrl + Enter to trigger confirm actions.
                if (e.key === 'Enter') {
```

**With this:**
```javascript
            if (e.ctrlKey) {
                const keyLow = e.key.toLowerCase();

                // Global Copy/Paste shortcuts
                const isExportModalOpen = document.querySelector('.ejcees-export-modal') !== null;
                if (!isExportTextMode && !isEditingComment && !isEditMode && !isExportModalOpen && !isEditingSettings) {
                    if (keyLow === 'c') {
                        // Let browser handle copy if user highlighted text manually
                        if (window.getSelection().toString() === "") {
                            e.preventDefault();
                            performCopy();
                        }
                        return;
                    }
                    if (keyLow === 'v') {
                        // Let browser handle paste if an input/textarea is focused
                        const activeElement = document.activeElement;
                        const isInputActive = activeElement && (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA');
                        if (!isInputActive) {
                            e.preventDefault();
                            performPaste();
                        }
                        return;
                    }
                }

                // Tool Button Shortcuts
                const toolShortcuts = {
                    'n': 'tool-new',
                    'o': 'tool-open',
                    'e': 'tool-edit',
                    's': 'tool-save',
                    'r': 'tool-rotate',
                    'f': 'tool-flip',
                    'insert': 'tool-exp-svg'
                };

                if (toolShortcuts[keyLow]) {
                    e.preventDefault(); // Prevent browser defaults like "Save Page"
                    const btn = document.getElementById(toolShortcuts[keyLow]);
                    // Only trigger if the button is currently enabled/highlighted
                    if (btn && btn.classList.contains('enable')) {
                        btn.click();
                    }
                    return;
                }

                // Ctrl + Enter to trigger confirm actions.
                if (e.key === 'Enter') {
```
https://ejsoon.vip/
弈趣極光:享受思維樂趣
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 0 访客