DeepSeek Ctrl+Enter Send

允许在DeepSeek网页端使用Ctrl+Enter发送,任意其他Enter换行,同时支持底部输入框和历史编辑框

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

You will need to install an extension such as Tampermonkey to install this script.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

Advertisement:

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

Advertisement:

// ==UserScript==
// @name         DeepSeek Ctrl+Enter Send
// @name:zh_CN   DeepSeek仅Ctrl+Enter发送
// @namespace    https://greasyfork.org/zh-CN/users/1405279-knighthana
// @author       Knighthana;DeepSeek
// @version      [email protected]
// @description  允许在DeepSeek网页端使用Ctrl+Enter发送,任意其他Enter换行,同时支持底部输入框和历史编辑框
// @match        https://chat.deepseek.com/*
// @icon         https://www.deepseek.com/favicon.ico
// @grant        none
// @license      GNU GPLv3
// ==/UserScript==

(function() {
    'use strict';

    function isVisible(el) {
        return el && el.offsetParent !== null;
    }

    function findSendButton(textarea) {
        let bestBtn = null;
        let bestDepth = Infinity;
        let parent = textarea.parentElement;
        let depth = 0;
        const MAX_DEPTH = 10;

        while (parent && parent !== document.body && depth < MAX_DEPTH) {
            const btns = parent.querySelectorAll('.ds-button--primary');
            for (const btn of btns) {
                if (!isVisible(btn)) continue;
                const isCircle = btn.classList.contains('ds-button--circle');
                const isCapsuleSend = btn.classList.contains('ds-button--capsule') && btn.textContent.trim() === '发送';
                if (!isCircle && !isCapsuleSend) continue;

                const textareas = parent.querySelectorAll('textarea');
                if (textareas.length === 1 && textareas[0] === textarea) {
                    if (depth < bestDepth) {
                        bestDepth = depth;
                        bestBtn = btn;
                    }
                }
            }
            parent = parent.parentElement;
            depth++;
        }

        if (bestBtn) return bestBtn;

        // 后备全局查找
        const allBtns = document.querySelectorAll('.ds-button--primary');
        for (const btn of allBtns) {
            if (isVisible(btn) &&
                (btn.classList.contains('ds-button--circle') ||
                 (btn.classList.contains('ds-button--capsule') && btn.textContent.trim() === '发送'))) {
                return btn;
            }
        }
        return null;
    }

    function insertNewline(element) {
        if (element.tagName === 'TEXTAREA' || element.tagName === 'INPUT') {
            const start = element.selectionStart;
            const end = element.selectionEnd;
            const value = element.value;
            element.value = value.substring(0, start) + '\n' + value.substring(end);
            element.selectionStart = element.selectionEnd = start + 1;
            element.dispatchEvent(new Event('input', { bubbles: true }));
        } else if (element.isContentEditable) {
            document.execCommand('insertLineBreak');
        }
    }

    function simulateClick(el) {
        if (el) el.click();
    }

    let lastSendTime = 0;

    function handleEnter(event) {
        if (event.key !== 'Enter') return;
        const target = event.target;
        if (target.tagName !== 'TEXTAREA') return;

        event.preventDefault();
        event.stopPropagation();
        event.stopImmediatePropagation();

        if (event.type === 'keydown') {
            if (event.ctrlKey) {
                const now = Date.now();
                if (now - lastSendTime < 300) return;
                lastSendTime = now;

                const btn = findSendButton(target);
                if (btn) {
                    simulateClick(btn);
                } else {
                    console.warn('[脚本] 未找到关联发送按钮');
                }
            } else {
                insertNewline(target);
            }
        }
    }

    document.addEventListener('keydown', handleEnter, true);
    document.addEventListener('keyup', handleEnter, true);
})();