Greasy Fork

来自缓存

Greasy Fork is available in English.

给AI搜索网站添加q查询参数,支持deepseek,腾讯元宝,知乎直答,kimi,智谱glm,阿里qwen,minimax,字节豆包,gemini

从URL中提取q查询参数,填入对话框,提交搜索。deepseek:chat.deepseek.com/?q={query},腾讯元宝:yuanbao.tencent.com/?q={query},知乎直答:zhida.zhihu.com/?q={query},kimi:www.kimi.com/?q={query},智谱glm:chatglm.cn/?q={query}或chat.z.ai/?q={query},阿里qwen:chat.qwen.ai/?q={query}或www.qianwen.com/?q={query},minimax:agent.minimaxi.com/?q={query},字节豆包:www.doubao.com/?q={query},gemini:gemini.google.com/?q={query}。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         给AI搜索网站添加q查询参数,支持deepseek,腾讯元宝,知乎直答,kimi,智谱glm,阿里qwen,minimax,字节豆包,gemini
// @namespace    http://tampermonkey.net/
// @version      2026.2.14
// @description  从URL中提取q查询参数,填入对话框,提交搜索。deepseek:chat.deepseek.com/?q={query},腾讯元宝:yuanbao.tencent.com/?q={query},知乎直答:zhida.zhihu.com/?q={query},kimi:www.kimi.com/?q={query},智谱glm:chatglm.cn/?q={query}或chat.z.ai/?q={query},阿里qwen:chat.qwen.ai/?q={query}或www.qianwen.com/?q={query},minimax:agent.minimaxi.com/?q={query},字节豆包:www.doubao.com/?q={query},gemini:gemini.google.com/?q={query}。
// @author       smilingpoplar
// @match        https://chat.deepseek.com/*
// @match        https://yuanbao.tencent.com/*
// @match        https://zhida.zhihu.com/*
// @match        https://www.kimi.com/*
// @match        https://chatglm.cn/*
// @match        https://chat.qwen.ai/*
// @match        https://agent.minimaxi.com/*
// @match        https://www.doubao.com/*
// @match        https://gemini.google.com/*
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(async () => {
    'use strict';

    const waitForElement = (selector, timeout) => {
        return new Promise((resolve, reject) => {
            const elem = document.querySelector(selector);
            if (elem) return resolve(elem);

            let timer;
            if (typeof timeout === 'number' && timeout > 0) {
                timer = setTimeout(() => {
                    observer.disconnect();
                    reject(`在${timeout}ms内,未找到元素:${selector}`);
                }, timeout);
            }
            const observer = new MutationObserver(() => {
                const elem = document.querySelector(selector);
                if (elem) {
                    if (timer) clearTimeout(timer);
                    observer.disconnect();
                    resolve(elem);
                }
            });
            observer.observe(document.documentElement, { childList: true, subtree: true });
        });
    };
    const delay = (ms) => new Promise(res => setTimeout(res, ms));

    const getQuery = {
        search: () => {
            const url = new URL(window.location.href);
            const q = url.searchParams.get('q');
            if (q) {
                url.searchParams.delete('q');
                window.history.replaceState({}, '', url.toString());
            }
            return q;
        },
        hash: () => {
            const queryString = location.hash.substring(1);
            return new URLSearchParams(queryString).get('q');
        }
    };
    const simulateInput = {
        textContent: (elem, value) => {
            elem.textContent = value;
            elem.dispatchEvent(new InputEvent('input', { bubbles: true }));
        },
        textContentWithData: (elem, value) => {
            elem.textContent = value;
            elem.dispatchEvent(new InputEvent('input', { data: value, bubbles: true }));
        },
        value: (elem, value) => {
            elem.value = value;
            elem.dispatchEvent(new InputEvent('input', { bubbles: true }));
        },
        insertText: (elem, value) => {
            document.execCommand('insertText', false, value);
            elem.dispatchEvent(new InputEvent('input', { bubbles: true }));
        }
    };
    const simulateEnter = {
        keyboard: (event = 'keydown') => (elem) => {
            elem.dispatchEvent(new KeyboardEvent(event, { key: 'Enter', keyCode: 13, bubbles: true }));
        },
        react: (elem) => {
            const getReactProps = el => el[Object.keys(el).find(k => k.startsWith('__reactProps$'))];
            getReactProps(elem)?.onKeyDown?.({
                key: "Enter",
                code: "Enter",
                keyCode: 13,
                which: 13,
                preventDefault: () => { },
                stopPropagation: () => { },
            });
        }
    };

    const defaultConfig = {
        getQuery: getQuery.search,
        selector: 'div[contenteditable="true"]',
        simulateInput: simulateInput.textContent,
        simulateEnter: simulateEnter.keyboard()
    };
    const siteConfigs = {
        'chat.deepseek.com': {
            selector: 'textarea'
        },
        'yuanbao.tencent.com': {
            beforeInput: async () => {
                // 在.input-guide-v2出现前的对话会被清空,所以等它加载
                await waitForElement('.input-guide-v2', 3000);
            }
        },
        'zhida.zhihu.com': {
            simulateInput: simulateInput.insertText,
            simulateEnter: simulateEnter.react
        },
        'www.kimi.com': {
            simulateInput: simulateInput.textContentWithData
        },
        'chatglm.cn': {
            selector: 'textarea',
            simulateInput: simulateInput.value
        },
        'chat.qwen.ai': {
            selector: 'textarea'
        },
        'www.doubao.com': {
            selector: 'textarea'
        }
    };


    const siteConfig = siteConfigs[window.location.hostname] ?? {};
    const config = { ...defaultConfig, ...siteConfig };
    const query = config.getQuery();
    if (!query) return;

    const editor = await waitForElement(config.selector);
    await config.beforeInput?.();

    editor.focus();
    await delay(100);
    config.simulateInput(editor, query);
    await delay(100);
    config.simulateEnter(editor);
})();