分享几个自己还有收集来的好用的油猴脚本

1. 知乎优化

安装地址
删除没用的垃圾内容

// ==UserScript==
// @name         知乎优化
// @namespace    http://tampermonkey.net/
// @version      0.4
// @description  Sets custom widths and hides specified elements on Zhihu
// @author       You
// @match        https://www.zhihu.com/*
// @match        http://www.zhihu.com/*
// @match        https://zhihu.com/*
// @match        http://zhihu.com/*
// @grant        none
// @license MIT
// @downloadURL https://update.greasyfork.org/scripts/529684/%E7%9F%A5%E4%B9%8E%E4%BC%98%E5%8C%96.user.js
// @updateURL https://update.greasyfork.org/scripts/529684/%E7%9F%A5%E4%B9%8E%E4%BC%98%E5%8C%96.meta.js
// ==/UserScript==
(function() {
    'use strict';
    // Function to apply width change
    function setMainColumnWidth() {
        const mainColumn = document.querySelector('.Topstory-mainColumn');
        if (mainColumn) {
            mainColumn.style.width = '100%';
            console.log('Zhihu Main Column width set to 100%');
        }
    }

    // Function to apply width change for Question pages
    function setQuestionMainColumnWidth() {
        const mainColumn = document.querySelector('.Question-mainColumn');
        if (mainColumn) {
            mainColumn.style.width = '100%';
            console.log('Zhihu Question Main Column width set to 100%');
        }
    }

    // Function to apply custom CSS styles
    function applyCustomStyles() {
        // Apply styles to .css-11p8nt5 elements
        const customElements = document.querySelectorAll('.css-11p8nt5');
        if (customElements.length > 0) {
            customElements.forEach(element => {
                element.style.maxWidth = '0px';
                element.style.minWidth = '950px';
                console.log('Applied custom styles to .css-11p8nt5');
            });
        }
        const customElements2 = document.querySelectorAll('.css-1kjxdzv');
        if (customElements2.length > 0) {
            customElements2.forEach(element => {
                element.style.maxWidth = '0px';
                element.style.minWidth = '950px';
                console.log('Applied custom styles to .css-1kjxdzv');
            });
        }


    }

    // Function to hide the specified elements
    function hideSpecifiedElements() {
        // Original element to hide
        const elementsToHide1 = document.querySelectorAll('.css-1qyytj7 > div');
        if (elementsToHide1.length > 0) {
            elementsToHide1.forEach(element => {
                element.style.display = 'none';
                console.log('Hidden element with class .css-1qyytj7 > div');
            });
        }

        // New elements to hide
        // 1. Elements with class .css-29q9fa
        const elementsToHide2 = document.querySelectorAll('.css-29q9fa');
        if (elementsToHide2.length > 0) {
            elementsToHide2.forEach(element => {
                element.style.display = 'none';
                console.log('Hidden element with class .css-29q9fa');
            });
        }

        // 2. Third AppHeader-Tab
        const thirdTab = document.querySelector('li.Tabs-item--noMeta.AppHeader-Tab.Tabs-item:nth-of-type(3)');
        if (thirdTab) {
            thirdTab.style.display = 'none';
            console.log('Hidden third AppHeader Tab');
        }

        // 3. Fourth AppHeader-Tab
        const fourthTab = document.querySelector('li.Tabs-item--noMeta.AppHeader-Tab.Tabs-item:nth-of-type(4)');
        if (fourthTab) {
            fourthTab.style.display = 'none';
            console.log('Hidden fourth AppHeader Tab');
        }

        // 4. Button with complex class chain
        const buttons = document.querySelectorAll('.css-18vqx7l > .fEPKGkUK5jyc4fUuT0QP.Button--plain.FEfUrdfMIKpQDJDqkjte.css-79elbk.Button');
        if (buttons.length > 0) {
            buttons.forEach(button => {
                button.style.display = 'none';
                console.log('Hidden specified button');
            });
        }
    }

    // Apply immediately for already loaded elements
    function applyAllChanges() {
        setMainColumnWidth();
        setQuestionMainColumnWidth();
        hideSpecifiedElements();
        applyCustomStyles();
    }

    // Initial application
    applyAllChanges();

    // Create a MutationObserver to handle dynamically loaded content
    const observer = new MutationObserver(function(mutations) {
        applyAllChanges();
    });

    // Start observing the document body for DOM changes
    observer.observe(document.body, { childList: true, subtree: true });
})();


Grok 限制显示脚本

来源自 Grok 限制显示脚本 - 开发调优 - LINUX DO

// ==UserScript==
// @name         Grok Rate Limits Viewer
// @namespace    https://grok.com/
// @version      1.5
// @description  显示Grok API的速率限制信息
// @author       Neuroplexus
// @match        https://grok.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    // 调试模式设置
    const DEBUG_MODE = false; // 设置为true开启调试模式
    const DEBUG_VALUES = {
        DEFAULT: { remainingQueries: 5, totalQueries: 25, windowSizeSeconds: 3600 },
        REASONING: { remainingQueries: 2, totalQueries: 10, windowSizeSeconds: 3600 },
        DEEPSEARCH: { remainingQueries: 0, totalQueries: 5, windowSizeSeconds: 3600 }
    };

    // 添加样式
    GM_addStyle(`
        #rate-limits-button {
            position: relative;
        }

        #rate-limits-container {
            position: fixed;
            width: 320px;
            background-color: #1a1a1a;
            border-radius: 16px;
            box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
            z-index: 9999;
            font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
            color: #ffffff;
            overflow: hidden;
            transition: opacity 0.2s ease, transform 0.2s ease;
            border: 1px solid #333333;
        }

        #rate-limits-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 16px 20px;
            background-color: #222222;
            cursor: move;
            user-select: none;
            border-bottom: 1px solid #333333;
        }

        #rate-limits-title {
            font-weight: 500;
            font-size: 14px;
            display: flex;
            align-items: center;
            gap: 10px;
            color: #ffffff;
        }

        #rate-limits-controls {
            display: flex;
            gap: 12px;
        }

        .rate-limits-control-button {
            background: transparent;
            border: none;
            color: #cccccc;
            cursor: pointer;
            padding: 6px;
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: background-color 0.2s ease;
        }

        .rate-limits-control-button:hover {
            background-color: #333333;
        }

        #rate-limits-content {
            padding: 24px;
        }

        .rate-limit-section {
            margin-bottom: 24px;
        }

        .rate-limit-section:last-child {
            margin-bottom: 0;
        }

        .rate-limit-title {
            font-weight: 500;
            font-size: 13px;
            margin-bottom: 12px;
            color: #aaaaaa;
        }

        .rate-limit-info {
            display: flex;
            justify-content: space-between;
            font-size: 13px;
            margin-bottom: 8px;
        }

        .rate-limit-progress-container {
            height: 6px;
            background-color: #333333;
            border-radius: 3px;
            overflow: hidden;
            margin-top: 10px;
        }

        .rate-limit-progress-bar {
            height: 100%;
            background-color: #3a8df4;
            border-radius: 3px;
            transition: width 0.3s ease;
        }

        .rate-limit-warning .rate-limit-progress-bar {
            background-color: #f0ad4e;
        }

        .rate-limit-danger .rate-limit-progress-bar {
            background-color: #d9534f;
        }

        .rate-limit-time {
            font-size: 11px;
            color: #888888;
            margin-top: 8px;
            text-align: right;
        }

        /* 徽章容器样式 */
        .badge-container {
            display: inline-flex;
            align-items: center;
            overflow: hidden;
            transition: width 0.3s ease, margin 0.3s ease;
            height: 90%;
            vertical-align: middle;
            width: 0px; /* 初始宽度为0 */
        }

        /* 徽章样式 */
        .rate-limit-badge {
            background-color: white;
            color: black;
            font-size: 10px;
            font-weight: 500;
            padding: 0 6px;
            border-radius: 10px;
            display: flex;
            align-items: center;
            white-space: nowrap;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
            height: 100%;
        }

        /* 状态指示点 */
        .rate-limit-badge::before {
            content: '';
            display: none;
            width: 6px;
            height: 6px;
            border-radius: 50%;
            margin-right: 4px;
            flex-shrink: 0;
        }

        .rate-limit-badge.warning::before {
            display: block;
            background-color: #f0ad4e;
        }

        .rate-limit-badge.danger::before {
            display: block;
            background-color: #d9534f;
        }

        /* 用完次数的按钮样式 */
        .rate-limit-depleted {
            position: relative;
        }

        .rate-limit-depleted::after {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(217, 83, 79, 0.3);
            pointer-events: none;
            border-radius: inherit;
        }

        /* 特定元素的徽章容器样式 */
        #radix-\\:r14\\: .badge-container {
            margin-right: 0px; /* 初始无margin */
        }

        /* 调试模式指示器 */
        .debug-mode-indicator {
            position: absolute;
            top: 16px;
            right: 16px;
            background-color: #d9534f;
            color: white;
            font-size: 10px;
            padding: 2px 6px;
            border-radius: 10px;
            font-weight: bold;
        }
    `);

    // 创建速率限制按钮
    function createRateLimitsButton() {
        const buttonContainer = document.createElement('a');
        buttonContainer.id = 'rate-limits-button';
        buttonContainer.className = 'inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium leading-[normal] cursor-pointer focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-default [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:-mx-0.5 text-primary hover:bg-button-ghost-hover h-10 w-10 rounded-full';
        buttonContainer.setAttribute('type', 'button');
        buttonContainer.setAttribute('data-state', 'closed');
        buttonContainer.innerHTML = `
            <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="20" width="20" xmlns="http://www.w3.org/2000/svg">
                <path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"></path>
                <path d="M12 6c-3.309 0-6 2.691-6 6s2.691 6 6 6 6-2.691 6-6-2.691-6-6-6zm0 10c-2.206 0-4-1.794-4-4s1.794-4 4-4 4 1.794 4 4-1.794 4-4 4z"></path>
                <path d="M12 8c-2.206 0-4 1.794-4 4s1.794 4 4 4 4-1.794 4-4-1.794-4-4-4zm0 6c-1.084 0-2-.916-2-2s.916-2 2-2 2 .916 2 2-.916 2-2 2z"></path>
            </svg>
        `;

        return buttonContainer;
    }

    // 创建速率限制窗口
    function createRateLimitsContainer() {
        const container = document.createElement('div');
        container.id = 'rate-limits-container';
        container.style.display = GM_getValue('rateLimitsVisible', 'none');

        // 从存储中获取位置
        const position = GM_getValue('rateLimitsPosition', { x: 20, y: 80 });
        container.style.left = `${position.x}px`;
        container.style.top = `${position.y}px`;

        container.innerHTML = `
            <div id="rate-limits-header">
                <div id="rate-limits-title">
                    <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="16" width="16" xmlns="http://www.w3.org/2000/svg">
                        <path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"></path>
                        <path d="M12 6c-3.309 0-6 2.691-6 6s2.691 6 6 6 6-2.691 6-6-2.691-6-6-6zm0 10c-2.206 0-4-1.794-4-4s1.794-4 4-4 4 1.794 4 4-1.794 4-4 4z"></path>
                        <path d="M12 8c-2.206 0-4 1.794-4 4s1.794 4 4 4 4-1.794 4-4-1.794-4-4-4zm0 6c-1.084 0-2-.916-2-2s.916-2 2-2 2 .916 2 2-.916 2-2 2z"></path>
                    </svg>
                    速率限制
                </div>
                <div id="rate-limits-controls">
                    <button id="rate-limits-refresh" class="rate-limits-control-button" title="刷新">
                        <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="16" width="16" xmlns="http://www.w3.org/2000/svg">
                            <path d="M10 11H7.101l.001-.009a4.956 4.956 0 0 1 .752-1.787 5.054 5.054 0 0 1 2.2-1.811c.302-.128.617-.226.938-.291a5.078 5.078 0 0 1 2.018 0 4.978 4.978 0 0 1 2.525 1.361l1.416-1.412a7.036 7.036 0 0 0-2.224-1.501 6.921 6.921 0 0 0-1.315-.408 7.079 7.079 0 0 0-2.819 0 6.94 6.94 0 0 0-1.316.409 7.04 7.04 0 0 0-3.08 2.534 6.978 6.978 0 0 0-1.054 2.505c-.028.135-.043.273-.063.41H2l4 4 4-4zm4 2h2.899l-.001.008a4.976 4.976 0 0 1-2.103 3.138 4.943 4.943 0 0 1-1.787.752 5.073 5.073 0 0 1-2.017 0 4.956 4.956 0 0 1-1.787-.752 5.072 5.072 0 0 1-.74-.61L7.05 16.95a7.032 7.032 0 0 0 2.225 1.5c.424.18.867.317 1.315.408a7.07 7.07 0 0 0 2.818 0 7.031 7.031 0 0 0 4.395-2.945 6.974 6.974 0 0 0 1.053-2.503c.027-.135.043-.273.063-.41H22l-4-4-4 4z"></path>
                        </svg>
                    </button>
                    <button id="rate-limits-close" class="rate-limits-control-button" title="关闭">
                        <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="16" width="16" xmlns="http://www.w3.org/2000/svg">
                            <path d="m16.192 6.344-4.243 4.242-4.242-4.242-1.414 1.414L10.535 12l-4.242 4.242 1.414 1.414 4.242-4.242 4.243 4.242 1.414-1.414L13.364 12l4.242-4.242z"></path>
                        </svg>
                    </button>
                </div>
            </div>
            <div id="rate-limits-content">
                <div class="rate-limit-section" id="default-rate-limit">
                    <div class="rate-limit-title">默认请求</div>
                    <div class="rate-limit-info">
                        <span>剩余请求数</span>
                        <span id="default-remaining">--/--</span>
                    </div>
                    <div class="rate-limit-progress-container">
                        <div class="rate-limit-progress-bar" style="width: 0%"></div>
                    </div>
                    <div class="rate-limit-time" id="default-time">窗口: -- 小时</div>
                </div>
                <div class="rate-limit-section" id="reasoning-rate-limit">
                    <div class="rate-limit-title">推理请求</div>
                    <div class="rate-limit-info">
                        <span>剩余请求数</span>
                        <span id="reasoning-remaining">--/--</span>
                    </div>
                    <div class="rate-limit-progress-container">
                        <div class="rate-limit-progress-bar" style="width: 0%"></div>
                    </div>
                    <div class="rate-limit-time" id="reasoning-time">窗口: -- 小时</div>
                </div>
                <div class="rate-limit-section" id="deepsearch-rate-limit">
                    <div class="rate-limit-title">深度搜索</div>
                    <div class="rate-limit-info">
                        <span>剩余请求数</span>
                        <span id="deepsearch-remaining">--/--</span>
                    </div>
                    <div class="rate-limit-progress-container">
                        <div class="rate-limit-progress-bar" style="width: 0%"></div>
                    </div>
                    <div class="rate-limit-time" id="deepsearch-time">窗口: -- 小时</div>
                </div>
            </div>
        `;

        // 如果是调试模式,添加指示器
        if (DEBUG_MODE) {
            const debugIndicator = document.createElement('div');
            debugIndicator.className = 'debug-mode-indicator';
            debugIndicator.textContent = 'DEBUG';
            container.appendChild(debugIndicator);
        }

        return container;
    }

    // 创建徽章元素
    function createBadge(type, position = 'end') {
        // 创建徽章容器
        const badgeContainer = document.createElement('div');
        badgeContainer.className = 'badge-container';
        badgeContainer.id = `${type.toLowerCase()}-badge-container`;

        // 创建徽章
        const badge = document.createElement('div');
        badge.className = 'rate-limit-badge';
        badge.id = `${type.toLowerCase()}-badge`;
        badge.textContent = '--/--';

        badgeContainer.appendChild(badge);
        return badgeContainer;
    }

    // 更新徽章信息
    function updateBadge(type, data) {
        const badgeContainer = document.getElementById(`${type.toLowerCase()}-badge-container`);
        if (!badgeContainer) return;

        const badge = document.getElementById(`${type.toLowerCase()}-badge`);
        if (!badge) return;

        const parentElement = badgeContainer.parentElement;
        if (!parentElement) return;

        if (data) {
            const { remainingQueries, totalQueries } = data;
            const badgeText = `${remainingQueries}/${totalQueries}`;

            badge.textContent = badgeText;

            // 移除所有状态类
            badge.classList.remove('warning', 'danger');
            parentElement.classList.remove('rate-limit-depleted');

            // 设置状态
            if (remainingQueries === 0) {
                badge.classList.add('danger');
                parentElement.classList.add('rate-limit-depleted');
            } else if (remainingQueries <= 3) {
                badge.classList.add('warning');
            }
        } else {
            badge.textContent = '--/--';
            badge.classList.remove('warning', 'danger');
            parentElement.classList.remove('rate-limit-depleted');
        }
    }

    // 隐藏徽章
    function hideBadge(type) {
        const badgeContainer = document.getElementById(`${type.toLowerCase()}-badge-container`);
        if (badgeContainer) {
            badgeContainer.style.width = '0px';

            if (badgeContainer.parentElement && badgeContainer.parentElement.id === 'radix-:r14:') {
                badgeContainer.style.marginRight = '0px';
            } else {
                badgeContainer.style.marginLeft = '0px';
            }
        }
    }

    // 显示徽章
    function showBadge(type) {
        const badgeContainer = document.getElementById(`${type.toLowerCase()}-badge-container`);
        const badge = document.getElementById(`${type.toLowerCase()}-badge`);

        if (badgeContainer && badge) {
            // 计算徽章实际宽度
            const tempBadge = badge.cloneNode(true);
            tempBadge.style.position = 'absolute';
            tempBadge.style.visibility = 'hidden';
            tempBadge.style.width = 'auto';
            document.body.appendChild(tempBadge);
            const badgeWidth = tempBadge.offsetWidth;
            document.body.removeChild(tempBadge);

            // 设置容器宽度
            if (badgeContainer.parentElement && badgeContainer.parentElement.id === 'radix-:r14:') {
                badgeContainer.style.width = `${badgeWidth}px`;
                badgeContainer.style.marginRight = '6px';
            } else {
                badgeContainer.style.width = `${badgeWidth}px`;
                badgeContainer.style.marginLeft = '6px';
            }
        }
    }

    // 将秒转换为小时,保留一位小数
    function secondsToHours(seconds) {
        return (seconds / 3600).toFixed(1);
    }

    // 更新速率限制信息
    function updateRateLimitInfo(type, data) {
        const section = document.getElementById(`${type.toLowerCase()}-rate-limit`);
        if (!section) return;

        const remaining = document.getElementById(`${type.toLowerCase()}-remaining`);
        const timeElement = document.getElementById(`${type.toLowerCase()}-time`);
        const progressBar = section.querySelector('.rate-limit-progress-bar');

        // 如果是调试模式,使用调试值
        let displayData = data;
        if (DEBUG_MODE && DEBUG_VALUES[type]) {
            displayData = DEBUG_VALUES[type];
        }

        if (displayData) {
            const { remainingQueries, totalQueries, windowSizeSeconds } = displayData;
            const percentage = (remainingQueries / totalQueries) * 100;

            remaining.textContent = `${remainingQueries}/${totalQueries}`;
            // 将秒转换为小时显示
            timeElement.textContent = `窗口: ${secondsToHours(windowSizeSeconds)} 小时`;
            progressBar.style.width = `${percentage}%`;

            // 设置颜色状态
            section.classList.remove('rate-limit-warning', 'rate-limit-danger');
            if (remainingQueries === 0) {
                section.classList.add('rate-limit-danger');
            } else if (remainingQueries <= 3) {
                section.classList.add('rate-limit-warning');
            }

            // 更新徽章
            updateBadge(type, displayData);
        } else {
            remaining.textContent = '--/--';
            timeElement.textContent = '窗口: -- 小时';
            progressBar.style.width = '0%';
            updateBadge(type, null);
        }
    }

    // 发送速率限制请求
    async function fetchRateLimit(type) {
        // 如果是调试模式,直接使用调试值并更新UI
        if (DEBUG_MODE && DEBUG_VALUES[type]) {
            updateRateLimitInfo(type, DEBUG_VALUES[type]);
            return DEBUG_VALUES[type];
        }

        try {
            const response = await fetch('/rest/rate-limits', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    requestKind: type,
                    modelName: 'grok-3'
                })
            });

            if (response.ok) {
                const data = await response.json();
                updateRateLimitInfo(type, data);
                return data;
            } else {
                console.error(`获取${type}速率限制失败:`, response.status);
                updateRateLimitInfo(type, null);
            }
        } catch (error) {
            console.error(`获取${type}速率限制出错:`, error);
            updateRateLimitInfo(type, null);
        }
        return null;
    }

    // 刷新所有速率限制
    async function refreshAllRateLimits() {
        if (DEBUG_MODE) {
            // 在调试模式下,直接使用调试值更新所有类型
            updateRateLimitInfo('DEFAULT', DEBUG_VALUES['DEFAULT']);
            updateRateLimitInfo('REASONING', DEBUG_VALUES['REASONING']);
            updateRateLimitInfo('DEEPSEARCH', DEBUG_VALUES['DEEPSEARCH']);

            // 更新上次刷新时间
            lastRefreshTime = Date.now();
            scheduleNextRefresh();
            return;
        }

        // 非调试模式下,正常请求API
        await Promise.all([
            fetchRateLimit('DEFAULT'),
            fetchRateLimit('REASONING'),
            fetchRateLimit('DEEPSEARCH')
        ]);

        // 更新上次刷新时间
        lastRefreshTime = Date.now();
        scheduleNextRefresh();
    }

    // 为指定按钮添加徽章
    function addBadgesToButtons() {
        // 为DeepSearch按钮添加徽章
        const deepSearchButton = document.querySelector('button.overflow-hidden:nth-child(1)');
        if (deepSearchButton && !deepSearchButton.querySelector('#deepsearch-badge-container')) {
            const badge = createBadge('DEEPSEARCH');
            deepSearchButton.appendChild(badge);

            // 添加鼠标事件
            deepSearchButton.addEventListener('mouseenter', () => showBadge('DEEPSEARCH'));
            deepSearchButton.addEventListener('mouseleave', () => hideBadge('DEEPSEARCH'));

            // 如果是调试模式,立即更新徽章
            if (DEBUG_MODE && DEBUG_VALUES['DEEPSEARCH']) {
                updateBadge('DEEPSEARCH', DEBUG_VALUES['DEEPSEARCH']);
            }
        }

        // 为Think按钮添加徽章
        const thinkButton = document.querySelector('button.gap-2:nth-child(2)');
        if (thinkButton && !thinkButton.querySelector('#reasoning-badge-container')) {
            const badge = createBadge('REASONING');
            thinkButton.appendChild(badge);

            // 添加鼠标事件
            thinkButton.addEventListener('mouseenter', () => showBadge('REASONING'));
            thinkButton.addEventListener('mouseleave', () => hideBadge('REASONING'));

            // 如果是调试模式,立即更新徽章
            if (DEBUG_MODE && DEBUG_VALUES['REASONING']) {
                updateBadge('REASONING', DEBUG_VALUES['REASONING']);
            }
        }

        // 为grok3按钮添加徽章 - 在最前方插入
        const grokButton = document.querySelector('#radix-\\:r14\\:');
        if (grokButton && !grokButton.querySelector('#default-badge-container')) {
            const badge = createBadge('DEFAULT', 'start');
            grokButton.insertBefore(badge, grokButton.firstChild);

            // 添加鼠标事件
            grokButton.addEventListener('mouseenter', () => showBadge('DEFAULT'));
            grokButton.addEventListener('mouseleave', () => hideBadge('DEFAULT'));

            // 如果是调试模式,立即更新徽章
            if (DEBUG_MODE && DEBUG_VALUES['DEFAULT']) {
                updateBadge('DEFAULT', DEBUG_VALUES['DEFAULT']);
            }
        }
    }

    // 拦截 fetch 请求
    const originalFetch = window.fetch;
    window.fetch = async function(input, init) {
        const response = await originalFetch(input, init);

        // 如果是调试模式,不处理实际API响应
        if (DEBUG_MODE) {
            return response;
        }

        // 克隆响应以便我们可以读取它
        if (input && input.toString().includes('/rest/rate-limits')) {
            const clonedResponse = response.clone();
            try {
                const data = await clonedResponse.json();
                if (init && init.body) {
                    const body = JSON.parse(init.body);
                    updateRateLimitInfo(body.requestKind, data);
                    lastRefreshTime = Date.now();
                    scheduleNextRefresh();
                }
            } catch (e) {
                console.error('解析速率限制响应失败:', e);
            }
        }

        return response;
    };

    // 拦截 XMLHttpRequest
    const originalXHROpen = XMLHttpRequest.prototype.open;
    const originalXHRSend = XMLHttpRequest.prototype.send;

    XMLHttpRequest.prototype.open = function(method, url, ...args) {
        this._url = url;
        return originalXHROpen.apply(this, [method, url, ...args]);
    };

    XMLHttpRequest.prototype.send = function(body) {
        // 如果是调试模式,不处理实际API响应
        if (DEBUG_MODE) {
            return originalXHRSend.apply(this, arguments);
        }

        if (this._url && this._url.toString().includes('/rest/rate-limits')) {
            const originalOnLoad = this.onload;
            this.onload = function() {
                try {
                    if (this.responseText) {
                        const data = JSON.parse(this.responseText);
                        if (body) {
                            const requestBody = JSON.parse(body);
                            updateRateLimitInfo(requestBody.requestKind, data);
                            lastRefreshTime = Date.now();
                            scheduleNextRefresh();
                        }
                    }
                } catch (e) {
                    console.error('解析速率限制响应失败:', e);
                }

                if (originalOnLoad) {
                    originalOnLoad.apply(this);
                }
            };
        }

        return originalXHRSend.apply(this, arguments);
    };

    // 设置定时刷新
    let refreshTimer = null;
    let lastRefreshTime = 0;
    const REFRESH_INTERVAL = 10 * 60 * 1000; // 10分钟

    function scheduleNextRefresh() {
        if (refreshTimer) {
            clearTimeout(refreshTimer);
        }

        const timeUntilNextRefresh = Math.max(0, REFRESH_INTERVAL - (Date.now() - lastRefreshTime));
        refreshTimer = setTimeout(refreshAllRateLimits, timeUntilNextRefresh);
    }

    // 拖拽功能
    function enableDrag(element, handle) {
        let isDragging = false;
        let offsetX, offsetY;

        handle.addEventListener('mousedown', (e) => {
            isDragging = true;
            offsetX = e.clientX - element.getBoundingClientRect().left;
            offsetY = e.clientY - element.getBoundingClientRect().top;
            e.preventDefault();
        });

        document.addEventListener('mousemove', (e) => {
            if (!isDragging) return;

            const x = e.clientX - offsetX;
            const y = e.clientY - offsetY;

            // 确保窗口不会超出屏幕
            const maxX = window.innerWidth - element.offsetWidth;
            const maxY = window.innerHeight - element.offsetHeight;

            element.style.left = `${Math.max(0, Math.min(x, maxX))}px`;
            element.style.top = `${Math.max(0, Math.min(y, maxY))}px`;
        });

        document.addEventListener('mouseup', () => {
            if (isDragging) {
                isDragging = false;

                // 保存位置
                GM_setValue('rateLimitsPosition', {
                    x: parseInt(element.style.left),
                    y: parseInt(element.style.top)
                });
            }
        });
    }

    // 监视DOM变化,为按钮添加徽章
    function setupButtonBadgeObserver() {
        const observer = new MutationObserver(() => {
            addBadgesToButtons();
        });

        observer.observe(document.body, { childList: true, subtree: true });
    }

    // 初始化函数
    function initialize() {
        // 等待目标元素加载
        const targetSelector = 'div.absolute:nth-child(3)';

        const observer = new MutationObserver((mutations, obs) => {
            const targetElement = document.querySelector(targetSelector);
            if (targetElement) {
                obs.disconnect();

                // 创建按钮和容器
                const button = createRateLimitsButton();
                const container = createRateLimitsContainer();

                // 添加到页面的最前面
                if (targetElement.firstChild) {
                    targetElement.insertBefore(button, targetElement.firstChild);
                } else {
                    targetElement.appendChild(button);
                }
                document.body.appendChild(container);

                // 启用拖拽
                const handle = document.getElementById('rate-limits-header');
                enableDrag(container, handle);

                // 绑定事件
                button.addEventListener('click', () => {
                    const isVisible = container.style.display !== 'none';
                    container.style.display = isVisible ? 'none' : 'block';
                    GM_setValue('rateLimitsVisible', isVisible ? 'none' : 'block');
                });

                document.getElementById('rate-limits-refresh').addEventListener('click', refreshAllRateLimits);
                document.getElementById('rate-limits-close').addEventListener('click', () => {
                    container.style.display = 'none';
                    GM_setValue('rateLimitsVisible', 'none');
                });

                // 初始加载数据
                refreshAllRateLimits();

                // 设置按钮徽章观察器
                setupButtonBadgeObserver();
            }
        });

        observer.observe(document.body, { childList: true, subtree: true });
    }

    // 启动脚本
    initialize();
})();

3. grok 添加上传文件

来源自 让 Grok 支持上传文件 - 开发调优 / 开发调优, Lv1 - LINUX DO

// ==UserScript==
// @name         Grok 添加上传文件按钮
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  给 Grok 加上“上传文件按钮”
// @author       [email protected] & claude-3-7-sonnet
// @match        https://grok.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Function to find the target div and add the upload button
    function addUploadButton() {
        // Find the target div - using a selector that matches the structure provided
        const targetDiv = document.querySelector('.grow.flex.gap-1\\.5.max-w-full');

        if (!targetDiv) {
            console.log('Target div not found. Retrying in 1 second...');
            setTimeout(addUploadButton, 1000);
            return;
        }

        // Check if button already exists to avoid duplicates
        if (document.getElementById('custom-upload-button')) {
            return;
        }

        // Create the button element
        const uploadButton = document.createElement('button');
        uploadButton.id = 'custom-upload-button';
        uploadButton.className = 'gap-2 whitespace-nowrap text-sm font-medium leading-[normal] cursor-pointer focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-default [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:-mx-0.5 text-primary h-9 rounded-full px-3.5 py-2 border border-toggle-border overflow-hidden flex items-center justify-center bg-transparent hover:bg-toggle-hover';
        uploadButton.type = 'button';
        uploadButton.tabIndex = '0';
        uploadButton.setAttribute('aria-pressed', 'false');
        uploadButton.setAttribute('data-state', 'closed');

        // Create SVG icon for the button
        const svgIcon = `
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="stroke-[2] text-secondary">
            <path d="M12 15V3M12 3L7 8M12 3L17 8" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
            <path d="M20 17V19C20 20.1046 19.1046 21 18 21H6C4.89543 21 4 20.1046 4 19V17" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
        </svg>`;

        // Set button content with icon and text
        uploadButton.innerHTML = svgIcon + '<span>上传文件</span>';

        // Create hidden file input element
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.style.display = 'none';
        fileInput.id = 'hidden-file-input';
        document.body.appendChild(fileInput);

        // Add click event to the upload button
        uploadButton.addEventListener('click', function() {
            fileInput.click();
        });

        // Add change event to the file input
        fileInput.addEventListener('change', function(event) {
            if (event.target.files.length > 0) {
                const file = event.target.files[0];
                handleFileUpload(file);
            }
        });

        // Add the button to the target div
        targetDiv.appendChild(uploadButton);
        console.log('Upload button added successfully');
    }

    // Function to handle file upload
    function handleFileUpload(file) {
        console.log('File selected:', file.name);

        // You may need to customize this part based on how the website handles uploads
        // Option 1: If the website uses clipboard events, simulate a paste event
        try {
            // Create a ClipboardItem and add it to the clipboard
            const dataTransfer = new DataTransfer();
            dataTransfer.items.add(file);

            // Create and dispatch a paste event
            const pasteEvent = new ClipboardEvent('paste', {
                clipboardData: dataTransfer,
                bubbles: true
            });
            document.activeElement.dispatchEvent(pasteEvent);
            console.log('Paste event dispatched');
        } catch (error) {
            console.error('Error simulating paste:', error);

            // Option 2: If the website uses XMLHttpRequest or fetch for uploads
            // This is a placeholder - you'll need to customize this based on the actual upload endpoint
            const formData = new FormData();
            formData.append('file', file);

            // Example upload code - replace URL with the actual upload endpoint
            /*
            fetch('/upload-endpoint', {
                method: 'POST',
                body: formData
            })
            .then(response => response.json())
            .then(data => {
                console.log('Upload successful:', data);
            })
            .catch(error => {
                console.error('Error uploading file:', error);
            });
            */
        }
    }

    // Run the function after the page loads
    window.addEventListener('load', addUploadButton);

    // Also run it after a short delay in case the div is added dynamically
    setTimeout(addUploadButton, 2000);

    // Optional: Set up a MutationObserver to detect if the target div appears later
    const observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.addedNodes.length) {
                addUploadButton();
            }
        });
    });

    observer.observe(document.body, { childList: true, subtree: true });
})();

4. grok 显示用量

来源自 你们的网页版 grok 3 用超标过吗? - #8,来自 lkw123

// ==UserScript==
// @name         Grok Helper
// @namespace    https://github.com/BlueSkyXN/GPT-Models-Plus
// @version      0.1.1
// @author       BlueSkyXN
// @description  Monitor Grok API rate limits (DEFAULT, REASONING, DEEPSEARCH), show summary + detail on hover
// @match        https://grok.com/*
// @match        https://ubiquitous-lolly-397934.netlify.app/*
// @grant        GM_addStyle
// @supportURL   https://github.com/BlueSkyXN/GPT-Models-Plus
// @homepageURL  https://github.com/BlueSkyXN/GPT-Models-Plus
// @downloadURL https://github.com/BlueSkyXN/GPT-Models-Plus/blob/main/GrokHelper.js
// @updateURL https://github.com/BlueSkyXN/GPT-Models-Plus/blob/main/GrokHelper.js
// ==/UserScript==

(function() {
    'use strict';

    // 三种模式 -> 中文名称对应表
    const MODE_LABELS = {
        DEFAULT: '标准',
        REASONING: '思考',
        DEEPSEARCH: '深度'
    };

    // 我们需要查询的三种模式
    const REQUEST_KINDS = Object.keys(MODE_LABELS);

    // 添加自定义样式
    GM_addStyle(`
        .grok-monitor {
            position: fixed;
            left: 16px;
            top: 72px; /* 位于 logo 下方 */
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            font-size: 14px;
            z-index: 100;
            display: flex;
            flex-direction: column;
            align-items: flex-start;
            padding: 8px 12px;
            gap: 8px;
            border: 1px solid #ccc;          /* 灰色圆角线始终显示 */
            border-radius: 8px;
            background-color: #fff;          /* 背景白色,可按需改 */
            color: #1a1a1a;
            box-shadow: 0 2px 4px rgba(0,0,0,0.08); /* 轻微投影,可选 */
            transition: all 0.2s ease;
            opacity: 0.9;
        }

        /* 悬浮时增加不透明度 */
        .grok-monitor:hover {
            opacity: 1;
        }

        /* 小版本:只显示总结行 */
        .grok-monitor-summary {
            display: flex;
            align-items: center;
            gap: 6px;
            white-space: nowrap;
            font-weight: 500;
            font-size: 14px;
        }

        /* 指示灯 */
        .grok-monitor-indicator {
            width: 12px;
            height: 12px;
            border-radius: 50%;
            flex-shrink: 0;
            transition: background-color 0.2s ease;
        }

        /* 大版本:详细行,默认隐藏,悬浮时显示 */
        .grok-monitor-details {
            display: none;        /* 默认隐藏 */
            flex-direction: column;
            gap: 4px;
            font-size: 13px;
        }

        /* 悬浮时让 details 显示 */
        .grok-monitor:hover .grok-monitor-details {
            display: flex;
        }

        .grok-monitor-kind-row {
            display: flex;
            align-items: center;
            gap: 6px;
            white-space: nowrap;
        }

        .grok-monitor-kind-name {
            font-weight: 600;
        }

        /* 更新动画(请求中时可以使用) */
        .grok-monitor.updating .grok-monitor-indicator {
            animation: pulse 1s ease-in-out infinite;
        }

        @keyframes pulse {
            0%, 100% {
                transform: scale(1);
                opacity: 1;
            }
            50% {
                transform: scale(1.2);
                opacity: 0.7;
            }
        }

        /* 深色模式下可自行调整 */
        @media (prefers-color-scheme: dark) {
            .grok-monitor {
                background-color: #2b2b2b;
                color: #fff;
                border-color: #666;
            }
        }
    `);

    // 工具函数:格式化等待时间
    function formatWaitTime(seconds) {
        if (seconds <= 0) return '0m';
        const hours = Math.floor(seconds / 3600);
        const minutes = Math.floor((seconds % 3600) / 60);
        if (hours > 0 && minutes > 0) {
            return `${hours}h${minutes}m`;
        } else if (hours > 0) {
            return `${hours}h`;
        } else {
            return `${minutes}m`;
        }
    }

    // 创建监控器UI
    function createMonitor() {
        const monitor = document.createElement('div');
        monitor.className = 'grok-monitor';

        // ---- 小版本(默认显示) ----
        const summaryRow = document.createElement('div');
        summaryRow.className = 'grok-monitor-summary';

        // 剩余次数总和文本
        const sumSpan = document.createElement('span');
        sumSpan.textContent = '剩余总数: ...';

        // 指示灯
        const indicator = document.createElement('div');
        indicator.className = 'grok-monitor-indicator';

        summaryRow.appendChild(sumSpan);
        summaryRow.appendChild(indicator);

        // ---- 大版本(悬浮后展开) ----
        const details = document.createElement('div');
        details.className = 'grok-monitor-details';

        // 为每种模式添加一行
        REQUEST_KINDS.forEach(kind => {
            const row = document.createElement('div');
            row.className = 'grok-monitor-kind-row';

            // 中文名称
            const nameSpan = document.createElement('span');
            nameSpan.className = 'grok-monitor-kind-name';
            nameSpan.textContent = MODE_LABELS[kind];

            // 剩余/等待 文本
            const infoSpan = document.createElement('span');
            infoSpan.textContent = '...';

            row.appendChild(nameSpan);
            row.appendChild(infoSpan);
            details.appendChild(row);
        });

        // 组装
        monitor.appendChild(summaryRow);
        monitor.appendChild(details);

        document.body.appendChild(monitor);
        return monitor;
    }

    // 获取当前域名的基础URL
    function getBaseUrl() {
        return window.location.origin;
    }

    // 获取每种模式的限额
    async function fetchRateLimit(kind) {
        try {
            // 使用动态的基础URL
            const baseUrl = getBaseUrl();
            const response = await fetch(`${baseUrl}/rest/rate-limits`, {
                method: 'POST',
                headers: {
                    'accept': '*/*',
                    'content-type': 'application/json'
                },
                body: JSON.stringify({
                    requestKind: kind,
                    modelName: "grok-3"
                }),
                credentials: 'include'
            });

            if (response.ok) {
                return await response.json();
            } else {
                throw new Error(`Failed to fetch ${kind} rate limit`);
            }
        } catch (error) {
            console.error('Rate limit check failed:', error);
            return null;
        }
    }

    // 一次获取所有模式数据
    async function getAllRateLimits() {
        const results = {};
        for (const kind of REQUEST_KINDS) {
            // 可改成 Promise.all 并行请求,这里顺序也行
            results[kind] = await fetchRateLimit(kind);
        }
        return results;
    }

    // 更新UI
    function updateUI(results) {
        const monitor = document.querySelector('.grok-monitor');
        const sumSpan = monitor.querySelector('.grok-monitor-summary span');
        const indicator = monitor.querySelector('.grok-monitor-indicator');

        // 给指示灯加 "updating" 动画效果
        monitor.classList.add('updating');

        // 计算合计剩余次数
        let sum = 0;
        REQUEST_KINDS.forEach(kind => {
            const data = results[kind];
            if (data && data.remainingQueries > 0) {
                sum += data.remainingQueries;
            }
        });

        // 小版本文本:合计剩余
        sumSpan.textContent = `剩余总数: ${sum}`;

        // 指示灯颜色
        if (sum === 0) {
            indicator.style.backgroundColor = '#EF4444'; // 红色
        } else if (sum > 0 && sum < 5) {
            indicator.style.backgroundColor = '#F59E0B'; // 黄色
        } else {
            indicator.style.backgroundColor = '#10B981'; // 绿色
        }

        // 更新大版本详细数据
        const detailRows = monitor.querySelectorAll('.grok-monitor-kind-row');
        detailRows.forEach(row => {
            const label = row.querySelector('.grok-monitor-kind-name').textContent;
            const kind = Object.keys(MODE_LABELS).find(k => MODE_LABELS[k] === label);
            const data = results[kind];
            const infoSpan = row.querySelector('span:nth-child(2)');

            if (!data) {
                infoSpan.textContent = '获取失败';
                return;
            }

            const { remainingQueries, waitTimeSeconds } = data;
            if (remainingQueries > 0) {
                infoSpan.textContent = `剩余: ${remainingQueries}`;
            } else {
                infoSpan.textContent = `等待: ${formatWaitTime(waitTimeSeconds)}`;
            }
        });

        // 1s 后移除更新动画
        setTimeout(() => monitor.classList.remove('updating'), 1000);
    }

    // 定时检查
    async function checkRateLimits() {
        const results = await getAllRateLimits();
        updateUI(results);
    }

    // 初始化
    function init() {
        createMonitor();
        checkRateLimits(); // 立即检查一次
        setInterval(checkRateLimits, 30000); // 每 30s 检查
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();

5. fuclaude seesion切换

来自于 我和claude合作的切换sessionKey的油猴脚本,同时参考了几位大佬的帖子,适用于fuclaude! - 资源荟萃 - LINUX DO
个人更改

// ==UserScript==
// @name         claudeSessionKeySwitch
// @version      2.4
// @description  使用sessionKey自动登录claude(可拖拽圆形图标,双击显示选项面板)
// @match        https://claude.ai/*
// @match        https://demo.fuclaude.com/*
// @match        https://claude.asia/*
// @grant        GM_setValue
// @grant        GM_getValue
// @license      GNU GPLv3
// @namespace    https://greasyfork.org/users/1337296
// ==/UserScript==

(function() {
    'use strict';

    const tokens = [
        {name: 'name', key: 'key'},
    ];

    const createElem = (tag, styles) => {
        const elem = document.createElement(tag);
        Object.assign(elem.style, styles);
        return elem;
    };

    // Get saved position or use defaults
    const savedPosition = {
        left: GM_getValue('buttonLeft', 10),
        bottom: GM_getValue('buttonBottom', 10)
    };

    // Create circular toggle button
    const toggleButton = createElem('button', {
        width: '30px',
        height: '30px',
        borderRadius: '50%',
        backgroundColor: '#faf9f5',
        color: '#007bff',
        cursor: 'move',
        position: 'fixed',
        bottom: `${savedPosition.bottom}px`,
        left: `${savedPosition.left}px`,
        zIndex: '10000',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        boxShadow: '0 2px 5px rgba(0,0,0,0.1)',
        transition: 'background-color 0.3s ease',
        outline: 'none',
        padding: '0',
        userSelect: 'none',
        touchAction: 'none'
    });

    toggleButton.innerHTML = '🔑';

    const dropdownContainer = createElem('div', {
        position: 'fixed',
        backgroundColor: '#faf9f5',
        padding: '20px',
        borderRadius: '12px',
        boxShadow: '0 4px 20px rgba(0,0,0,0.15)',
        display: 'none',
        flexDirection: 'column',
        gap: '15px',
        width: '500px',
        maxHeight: '80vh',
        overflowY: 'auto',
        zIndex: '9999',
        border: '1px solid #e0e0e0',
        left: '50%',
        top: '50%',
        transform: 'translate(-50%, -50%)'
    });

    // Add title
    const titleContainer = createElem('div', {
        marginBottom: '15px',
        textAlign: 'center',
        borderBottom: '2px solid #eee',
        paddingBottom: '10px'
    });
    titleContainer.innerHTML = '<h2 style="margin:0;color:#333;font-size:18px;">Claude Session Key Switch</h2>';
    dropdownContainer.appendChild(titleContainer);

    // Create grid container for tokens
    const gridContainer = createElem('div', {
        display: 'grid',
        gridTemplateColumns: 'repeat(2, 1fr)',
        gap: '10px',
        margin: '10px 0'
    });

    // Get saved switch times
    const switchTimes = GM_getValue('switchTimes', {});

    tokens.forEach(token => {
        const tokenCard = createElem('div', {
            padding: '15px',
            borderRadius: '8px',
            backgroundColor: '#fff',
            border: '1px solid #ddd',
            cursor: 'pointer',
            transition: 'all 0.3s ease'
        });

    const lastSwitchTime = switchTimes[token.name] || '未使用';

// 计算时间差
let color = '#666'; // 默认颜色
if(lastSwitchTime !== '未使用') {
    const fiveHoursInMs = 5 * 60 * 60 * 1000; // 5小时转换为毫秒
    const switchTimestamp = new Date(lastSwitchTime).getTime();
    const currentTime = new Date().getTime();

    // 如果时间差大于5小时显示红色,否则显示绿色
    color = currentTime - switchTimestamp > fiveHoursInMs ? 'green' : 'red';
}

tokenCard.innerHTML = `
    <div style="font-weight:bold;color:#333;margin-bottom:5px">${token.name}</div>
<div style="font-size:12px;">上次切换: <span style="color:${color}">${lastSwitchTime}</span></div>
`;

        tokenCard.addEventListener('mouseover', () => {
            tokenCard.style.backgroundColor = '#f0f7ff';
            tokenCard.style.borderColor = '#007bff';
        });

        tokenCard.addEventListener('mouseout', () => {
            tokenCard.style.backgroundColor = '#fff';
            tokenCard.style.borderColor = '#ddd';
        });

      tokenCard.addEventListener('click', () => {
            // Update switch time
            const now = new Date().toLocaleString('zh-CN');
            switchTimes[token.name] = now;
            GM_setValue('switchTimes', switchTimes);

            // Update display
            tokenCard.querySelector('div:last-child').textContent = `上次切换: ${now}`;

            // Store selection and trigger login
            localStorage.setItem('claudeSelectedToken', token.key);
            handleTokenSelection(token.key);
        });

        gridContainer.appendChild(tokenCard);
    });

    dropdownContainer.appendChild(gridContainer);

    // Add info section
    const infoSection = createElem('div', {
        marginTop: '15px',
        padding: '10px',
        backgroundColor: '#f8f9fa',
        borderRadius: '6px',
        fontSize: '12px',
        color: '#666'
    });
    infoSection.innerHTML = '双击按钮展开/收起面板 • 拖拽按钮调整位置';
    dropdownContainer.appendChild(infoSection);

    let isDragging = false;
    let startX, startY;
    let buttonLeft = savedPosition.left;
    let buttonBottom = savedPosition.bottom;

    function onMouseDown(e) {
        if (e.target === toggleButton) {
            isDragging = true;
            const buttonRect = toggleButton.getBoundingClientRect();
            startX = e.clientX - buttonRect.left;
            startY = e.clientY - buttonRect.top;
            toggleButton.style.cursor = 'grabbing';
        }
    }

    function onMouseMove(e) {
        if (!isDragging) return;

        e.preventDefault();

        const newLeft = e.clientX - startX;
        const newTop = e.clientY - startY;

        // Calculate bottom position from top
        const bottom = window.innerHeight - newTop - toggleButton.offsetHeight;

        // Ensure button stays within window bounds
        const maxLeft = window.innerWidth - toggleButton.offsetWidth;
        const maxBottom = window.innerHeight - toggleButton.offsetHeight;

        buttonLeft = Math.min(Math.max(newLeft, 0), maxLeft);
        buttonBottom = Math.min(Math.max(bottom, 0), maxBottom);

        // Update button position
        toggleButton.style.left = `${buttonLeft}px`;
        toggleButton.style.bottom = `${buttonBottom}px`;
        toggleButton.style.top = 'auto';
    }

    function onMouseUp() {
        if (isDragging) {
            isDragging = false;
            toggleButton.style.cursor = 'move';

            // Save position to GM storage
            GM_setValue('buttonLeft', buttonLeft);
            GM_setValue('buttonBottom', buttonBottom);
        }
    }

    // Double click detection
    let lastClickTime = 0;
    toggleButton.addEventListener('click', (e) => {
        const clickTime = new Date().getTime();
        const timeDiff = clickTime - lastClickTime;

        if (timeDiff < 300) { // Double click threshold
            dropdownContainer.style.display = dropdownContainer.style.display === 'none' ? 'flex' : 'none';
            e.stopPropagation();
        }

        lastClickTime = clickTime;
    });

    // Add drag events
    toggleButton.addEventListener('mousedown', onMouseDown);
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup', onMouseUp);

    // Close dropdown when clicking outside
    document.addEventListener('click', (e) => {
        if (!dropdownContainer.contains(e.target) && e.target !== toggleButton) {
            dropdownContainer.style.display = 'none';
        }
    });

    function handleTokenSelection(token) {
        if (token === '') {
            console.log('Empty token selected. No action taken.');
        } else {
            autoLogin(token);
        }
    }

    function autoLogin(token) {
        const currentURL = window.location.href;
        let loginUrl;

        if (currentURL.startsWith('https://demo.fuclaude.com/')) {
            loginUrl = `https://demo.fuclaude.com/login_token?session_key=${token}`;
        } else if (currentURL.startsWith('https://claude.asia/')) {
            loginUrl = `https://claude.asia/login_token?session_key=${token}`;
        } else {
            loginUrl = `https://demo.fuclaude.com/login_token?session_key=${token}`;
        }

        window.location.href = loginUrl;
    }

    // Initialize the UI
    document.body.appendChild(dropdownContainer);
    document.body.appendChild(toggleButton);
})();

6. GitHub 中文化插件

开源地址 maboloshi/github-chinese: GitHub 汉化插件,GitHub 中文化界面。 (GitHub Translation To Chinese)
安装地址

7. 网盘有效性检查

网盘助手,自动识别并检查链接状态,自动填写密码并跳转。现已支持 :white_check_mark:百度网盘 :white_check_mark:蓝奏云 :white_check_mark:腾讯微云 :white_check_mark:阿里云盘 :white_check_mark:天翼云盘 :white_check_mark:123网盘 :white_check_mark:迅雷云盘 :white_check_mark:夸克网盘 :white_check_mark:奶牛网盘 :white_check_mark:文叔叔 :white_check_mark:115网盘 :white_check_mark:移动彩云
// @note 支持百度云、蓝奏云、腾讯微云、阿里云盘、天翼云盘、123网盘、夸克网盘、迅雷网盘、奶牛网盘、文叔叔、115网盘

安装地址

8. 星号密码显示助手

当鼠标停留在密码框时显示星号密码。再也不担心忘记密码和输错密码了。
开源地址
安装地址

大家可以推荐一下自己在用的。 :xhs_001::xhs_001:

70 Likes

感谢佬的推荐~

不错不错,收藏一波

感谢分享 都很有用

现在greasyfork好像被墙了…好烦…
推荐:
东方永页机。

牛呀,实用性很强

不错不错

第一个链接打开 显示 This page is used as an intermediate step to install a new userscript in Tampermonkey.
It should automatically be closed or redirected after the installation is complete.

The page is not intended to be viewed directly. Please visit the download section to install the extension.

很实用,github中文脚本,安装地址点不开

感谢分享

1 Like

我把代码粘上去了

很实用的工具,先收藏了,感谢分享 :laughing:

试试这个

https://github.com/maboloshi/github-chinese/raw/gh-pages/main.user.js

很好很强大,进我的收藏夹吃灰吧 :laughing:

2 Likes

这个可以,装上了,感谢大自然的馈赠

网页加速器

// ==UserScript==
// @name              网页加速器
// @namespace         https://github.com/syhyz1990/instantpage
// @version           1.4.3
// @author            YouXiaoHou
// @description       自动帮你加速网页中的超链接,加快打开网页的速度,实测符合条件的网页打开速度减少50%以上。
// @updateURL         https://www.youxiaohou.com/instantpage.user.js
// @downloadURL       https://www.youxiaohou.com/instantpage.user.js
// @license           AGPL
// @homepage          https://www.youxiaohou.com/tool/install-instantpage.html
// @supportURL        https://github.com/syhyz1990/instantpage
// @require           https://unpkg.com/[email protected]/dist/sweetalert2.min.js
// @resource          swalStyle https://unpkg.com/[email protected]/dist/sweetalert2.min.css
// @match             *://*/*
// @noframes
// @run-at            document-idle
// @grant             GM_openInTab
// @grant             GM_setValue
// @grant             GM_getValue
// @grant             GM_registerMenuCommand
// @grant             GM_getResourceText
// @icon              data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjggMTI4Ij48cGF0aCBkPSJNMCA3OWMwLTM1LjQgMjguNS02NCA2My45LTY0LjFzNjQuMSAyOC42IDY0LjEgNjRjMCA5LjQtMi4xIDE4LjQtNS43IDI2LjUtMSAyLjMtMi4zIDQuNi0zLjYgNi43LS40LjYtMSAxLTEuNyAxSDExYy0uNyAwLTEuMy0uNC0xLjctMS0xLjMtMi4yLTIuNS00LjQtMy42LTYuN0MyLjEgOTcuNCAwIDg4LjQgMCA3OXptMjQuNC0zOS43Yy01LjIgNS4xLTkuMiAxMS4xLTEyIDE3LjgtMyA2LjktNC41IDE0LjItNC41IDIxLjhhNTUuODYgNTUuODYgMCAwIDAgNC40IDIxLjhjLjcgMS42IDEuNCAzLjIgMi4yIDQuN2g5OC44Yy44LTEuNSAxLjYtMy4xIDIuMi00LjdhNTUuODYgNTUuODYgMCAwIDAgNC40LTIxLjggNTUuODYgNTUuODYgMCAwIDAtNC40LTIxLjhjLTIuOC02LjctNi45LTEyLjctMTItMTcuOC01LjEtNS4yLTExLjEtOS4yLTE3LjgtMTJhNTUuODYgNTUuODYgMCAwIDAtMjEuOC00LjQgNTUuODYgNTUuODYgMCAwIDAtMjEuOCA0LjRjLTYuNiAyLjgtMTIuNiA2LjgtMTcuNyAxMnoiIGZpbGw9IiM0NDQiLz48cGF0aCBkPSJNMTIuNCA1Ny4xYzIuOC02LjcgNi45LTEyLjcgMTItMTcuOCA1LjEtNS4yIDExLjEtOS4yIDE3LjgtMTJBNTUuODYgNTUuODYgMCAwIDEgNjQgMjIuOWE1NS44NiA1NS44NiAwIDAgMSAyMS44IDQuNGM2LjcgMi44IDEyLjcgNi45IDE3LjggMTIgNS4yIDUuMSA5LjIgMTEuMSAxMiAxNy44YTU1Ljg2IDU1Ljg2IDAgMCAxIDQuNCAyMS44IDU1Ljg2IDU1Ljg2IDAgMCAxLTQuNCAyMS44Yy0uNyAxLjYtMS40IDMuMi0yLjIgNC43SDE0LjZjLS44LTEuNS0xLjYtMy4xLTIuMi00LjdBNTUuODYgNTUuODYgMCAwIDEgOCA3OC45Yy0uMS03LjYgMS40LTE0LjkgNC40LTIxLjh6IiBmaWxsPSIjNjQ5OTUwIi8+PHBhdGggZD0iTTc3LjUgNjAuOUM2OCA4MS4yIDY0LjkgODQuNiA2NC42IDg1Yy0xLjUgMS41LTMuNSAyLjMtNS42IDIuM3MtNC4xLS44LTUuNi0yLjNhNy45MSA3LjkxIDAgMCAxIDAtMTEuMmMuMy0uNCAzLjgtMy40IDI0LjEtMTIuOXptMC04Yy0xLjEgMC0yLjMuMi0zLjQuOEM2My4yIDU4LjggNTEgNjQuOSA0Ny44IDY4LjFjLTYuMiA2LjItNi4yIDE2LjMgMCAyMi41IDMuMSAzLjEgNy4yIDQuNyAxMS4yIDQuN3M4LjEtMS42IDExLjItNC43YzMuMi0zLjIgOS4zLTE1LjQgMTQuNC0yNi4zIDIuNi01LjYtMS43LTExLjQtNy4xLTExLjR6TTYzLjkgMjkuOGMtMjcuMiAwLTQ5LjUgMjIuNi00OS4xIDQ5LjggMCAzLjYuNSA3LjIgMS4zIDEwLjYuNCAxLjggMiAzLjEgMy45IDMuMSAyLjYgMCA0LjQtMi40IDMuOS00LjktLjctMy0xLjEtNi4yLTEuMS05LjNBNDIuMDQgNDIuMDQgMCAwIDEgMjYgNjNjMi01IDUtOS40IDguOC0xMy4yUzQzIDQzLjEgNDcuOSA0MWE0Mi4wNCA0Mi4wNCAwIDAgMSAzMi4yIDBjNC45IDIuMSA5LjMgNS4xIDEzLjEgOC45Qzk3IDUzLjYgOTkuOSA1OCAxMDIgNjNhNDIuMDQgNDIuMDQgMCAwIDEgMy4yIDE2LjFjMCAzLjItLjQgNi4zLTEuMSA5LjMtLjYgMi41IDEuMyA0LjkgMy45IDQuOSAxLjggMCAzLjUtMS4zIDMuOS0zLjEuOC0zLjYgMS4zLTcuMyAxLjMtMTEuMSAwLTI3LjMtMjIuMS00OS4zLTQ5LjMtNDkuM3oiIGZpbGw9IiM0NDQiLz48L3N2Zz4=
// ==/UserScript==

(function () {
    'use strict';

    let util = {
        getValue(name) {
            return GM_getValue(name);
        },

        setValue(name, value) {
            GM_setValue(name, value);
        },

        include(str, arr) {
            str = str.replace(/[-_]/ig, '');
            for (let i = 0, l = arr.length; i < l; i++) {
                let val = arr[i];
                if (val !== '' && str.toLowerCase().indexOf(val.toLowerCase()) > -1) {
                    return true;
                }
            }
            return false;
        },

        addStyle(id, tag, css) {
            tag = tag || 'style';
            let doc = document, styleDom = doc.getElementById(id);
            if (styleDom) return;
            let style = doc.createElement(tag);
            style.rel = 'stylesheet';
            style.id = id;
            tag === 'style' ? style.innerHTML = css : style.href = css;
            doc.head.appendChild(style);
        },

        reg: {
            chrome: /^https?:\/\/chrome.google.com\/webstore\/.+?\/([a-z]{32})(?=[\/#?]|$)/,
            chromeNew: /^https?:\/\/chromewebstore.google.com\/.+?\/([a-z]{32})(?=[\/#?]|$)/,
            edge: /^https?:\/\/microsoftedge.microsoft.com\/addons\/.+?\/([a-z]{32})(?=[\/#?]|$)/,
            firefox: /^https?:\/\/(reviewers\.)?(addons\.mozilla\.org|addons(?:-dev)?\.allizom\.org)\/.*?(?:addon|review)\/([^/<>"'?#]+)/,
            microsoft: /^https?:\/\/(?:apps|www).microsoft.com\/(?:store|p)\/.+?\/([a-zA-Z\d]{10,})(?=[\/#?]|$)/,
        }
    };

    let main = {
        initValue() {
            let value = [{
                name: 'setting_success_times',
                value: 0
            }, {
                name: 'allow_external_links',
                value: true
            }, {
                name: 'allow_query_links',
                value: true
            }, {
                name: 'enable_store_link',
                value: true
            }, {
                name: 'enable_target_self',
                value: false
            }, {
                name: 'enable_animation',
                value: false
            }, {
                name: 'delay_on_hover',
                value: 65
            }, {
                name: 'exclude_list',
                value: ''
            }, {
                name: 'exclude_keyword',
                value: 'login\nlogout\nregister\nsignin\nsignup\nsignout\npay\ncreate\nedit\ndownload\ndel\nreset\nsubmit\ndoubleclick\ngoogleads\nexit'
            }];

            value.forEach((v) => {
                util.getValue(v.name) === undefined && util.setValue(v.name, v.value);
            });
        },

        registerMenuCommand() {
            GM_registerMenuCommand('🚀 已加速:' + util.getValue('setting_success_times') + '次', () => {
                Swal.fire({
                    showCancelButton: true,
                    title: '确定要重置加速次数吗?',
                    icon: 'warning',
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    customClass: {
                        popup: 'instant-popup',
                    },
                }).then((res) => {
                    if (res.isConfirmed) {
                        util.setValue('setting_success_times', 0);
                        history.go(0);
                    }
                });
            });
            GM_registerMenuCommand('⚙️ 设置', () => {
                let dom = `<div style="font-size: 1em;">
                              <label class="instant-setting-label">加速外部链接<input type="checkbox" id="S-External" ${util.getValue('allow_external_links') ? 'checked' : ''} class="instant-setting-checkbox"></label>
                              <label class="instant-setting-label"><span>加速含参数链接 <a href="https://www.youxiaohou.com/tool/install-instantpage.html#%E9%85%8D%E7%BD%AE%E8%AF%B4%E6%98%8E">详见</a></span><input type="checkbox" id="S-Query" ${util.getValue('allow_query_links') ? 'checked' : ''} 
                              class="instant-setting-checkbox"></label>
                              <label class="instant-setting-label">加速扩展/应用商店链接<input type="checkbox" id="S-Store" ${util.getValue('enable_store_link') ? 'checked' : ''} class="instant-setting-checkbox"></label>
                              <label class="instant-setting-label">加速链接在当前页打开<input type="checkbox" id="S-Target" ${util.getValue('enable_target_self') ? 'checked' : ''} class="instant-setting-checkbox"></label>
                              <label class="instant-setting-label">加速动画效果<input type="checkbox" id="S-Animate" ${util.getValue('enable_animation') ? 'checked' : ''} 
                              class="instant-setting-checkbox"></label>
                              <label class="instant-setting-label">链接预读延时(毫秒)<input type="number" min="65" id="S-Delay" value="${util.getValue('delay_on_hover')}" 
                              class="instant-setting-input"></label>
                              <label class="instant-setting-label-col">排除下列网址 <textarea placeholder="列表中的域名将不开启加速器,一行一个,例如:www.baidu.com" id="S-Exclude" class="instant-setting-textarea">${util.getValue('exclude_list')}</textarea></label>
                              <label class="instant-setting-label-col">排除下列关键词 <textarea placeholder="链接中含关键词将不开启加速器,一行一个,例如:logout" id="S-Exclude-Word" class="instant-setting-textarea">${util.getValue('exclude_keyword')}</textarea></label>
                            </div>`;
                Swal.fire({
                    title: '加速器配置',
                    html: dom,
                    showCloseButton: true,
                    confirmButtonText: '保存',
                    footer: '<div style="text-align: center;font-size: 1em;">点击查看 <a href="https://www.youxiaohou.com/tool/install-instantpage.html" target="_blank">使用说明</a>,助手免费开源,Powered by <a href="https://www.youxiaohou.com">油小猴</a></div>',
                    customClass: {
                        popup: 'instant-popup',
                    },
                }).then((res) => {
                    if (res.isConfirmed) {
                        history.go(0);
                    }
                });

                document.getElementById('S-External').addEventListener('change', (e) => {
                    util.setValue('allow_external_links', e.currentTarget.checked);
                });
                document.getElementById('S-Query').addEventListener('change', (e) => {
                    util.setValue('allow_query_links', e.currentTarget.checked);
                });
                document.getElementById('S-Store').addEventListener('change', (e) => {
                    util.setValue('enable_store_link', e.currentTarget.checked);
                });
                document.getElementById('S-Target').addEventListener('change', (e) => {
                    util.setValue('enable_target_self', e.currentTarget.checked);
                });
                document.getElementById('S-Animate').addEventListener('change', (e) => {
                    util.setValue('enable_animation', e.currentTarget.checked);
                });
                document.getElementById('S-Delay').addEventListener('change', (e) => {
                    util.setValue('delay_on_hover', e.currentTarget.value);
                });
                document.getElementById('S-Exclude').addEventListener('change', (e) => {
                    util.setValue('exclude_list', e.currentTarget.value);
                });
                document.getElementById('S-Exclude-Word').addEventListener('change', (e) => {
                    util.setValue('exclude_keyword', e.currentTarget.value);
                });
            });
        },

        //在排除名单里
        inExcludeList() {
            let exclude = util.getValue('exclude_list').split('\n');
            let host = location.host;
            return exclude.includes(host);
        },

        //加速主代码
        instantPage() {
            if (window.instantLoaded) return;
            let mouseoverTimer;
            let lastTouchTimestamp;
            const prefetches = new Set();
            const prefetchElement = document.createElement('link');
            const isSupported = prefetchElement.relList && prefetchElement.relList.supports && prefetchElement.relList.supports('prefetch')
                && window.IntersectionObserver && 'isIntersecting' in IntersectionObserverEntry.prototype;
            const isOnline = () => window.navigator.onLine;
            const allowQueryString = 'instantAllowQueryString' in document.body.dataset || util.getValue('allow_query_links');
            const allowExternalLinks = 'instantAllowExternalLinks' in document.body.dataset || util.getValue('allow_external_links');
            const useWhitelist = 'instantWhitelist' in document.body.dataset;
            const mousedownShortcut = 'instantMousedownShortcut' in document.body.dataset;
            const DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION = 1111;
            const enableAnimation = util.getValue('enable_animation');
            const enableTargetSelf = util.getValue('enable_target_self');
            const enableStoreLink = util.getValue('enable_store_link');
            window.instantLoaded = true;
            const excludeKeyword = util.getValue('exclude_keyword').split('\n');

            let delayOnHover = util.getValue('delay_on_hover');
            let useMousedown = false;
            let useMousedownOnly = false;
            let useViewport = false;

            if ('instantIntensity' in document.body.dataset) {
                const intensity = document.body.dataset.instantIntensity;

                if (intensity.substr(0, 'mousedown'.length) === 'mousedown') {
                    useMousedown = true;
                    if (intensity === 'mousedown-only') {
                        useMousedownOnly = true;
                    }
                } else if (intensity.substr(0, 'viewport'.length) === 'viewport') {
                    if (!(navigator.connection && (navigator.connection.saveData || (navigator.connection.effectiveType && navigator.connection.effectiveType.includes('2g'))))) {
                        if (intensity === "viewport") {
                            if (document.documentElement.clientWidth * document.documentElement.clientHeight < 450000) {
                                useViewport = true;
                            }
                        } else if (intensity === "viewport-all") {
                            useViewport = true;
                        }
                    }
                } else {
                    const milliseconds = parseInt(intensity);
                    if (!Number.isNaN(milliseconds)) {
                        delayOnHover = milliseconds;
                    }
                }
            }

            if (isSupported) {
                const eventListenersOptions = {
                    capture: true,
                    passive: true,
                };

                if (!useMousedownOnly) {
                    document.addEventListener('touchstart', touchstartListener, eventListenersOptions);
                }

                if (!useMousedown) {
                    document.addEventListener('mouseover', mouseoverListener, eventListenersOptions);
                } else if (!mousedownShortcut) {
                    document.addEventListener('mousedown', mousedownListener, eventListenersOptions);
                }

                if (mousedownShortcut) {
                    document.addEventListener('mousedown', mousedownShortcutListener, eventListenersOptions);
                }


                if (useViewport) {
                    let triggeringFunction;
                    if (window.requestIdleCallback) {
                        triggeringFunction = (callback) => {
                            requestIdleCallback(callback, {
                                timeout: 1500,
                            });
                        };
                    } else {
                        triggeringFunction = (callback) => {
                            callback();
                        };
                    }

                    triggeringFunction(() => {
                        const intersectionObserver = new IntersectionObserver((entries) => {
                            entries.forEach((entry) => {
                                if (entry.isIntersecting) {
                                    const linkElement = entry.target;
                                    intersectionObserver.unobserve(linkElement);
                                    preload(linkElement);
                                }
                            });
                        });

                        document.querySelectorAll('a').forEach((linkElement) => {
                            if (isPreloadable(linkElement)) {
                                intersectionObserver.observe(linkElement);
                            }
                        });
                    });
                }
            }

            function touchstartListener(event) {
                /* Chrome on Android calls mouseover before touchcancel so `lastTouchTimestamp`
                 * must be assigned on touchstart to be measured on mouseover. */
                lastTouchTimestamp = performance.now();

                const linkElement = event.target.closest('a');

                if (!isPreloadable(linkElement)) {
                    return;
                }

                preload(linkElement);
            }

            function mouseoverListener(event) {
                if (performance.now() - lastTouchTimestamp < DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION) {
                    return;
                }

                if (!('closest' in event.target)) {
                    // Without this check sometimes an error “event.target.closest is not a function” is thrown, for unknown reasons
                    // That error denotes that `event.target` isn’t undefined. My best guess is that it’s the Document.

                    // Details could be gleaned from throwing such an error:
                    //throw new TypeError(`instant.page non-element event target: timeStamp=${~~event.timeStamp}, type=${event.type}, typeof=${typeof event.target}, nodeType=${event.target.nodeType}, nodeName=${event.target.nodeName}, viewport=${innerWidth}x${innerHeight}, coords=${event.clientX}x${event.clientY}, scroll=${scrollX}x${scrollY}`)
                    return
                }

                const linkElement = event.target.closest('a');

                if (!isPreloadable(linkElement)) {
                    return;
                }

                linkElement.addEventListener('mouseout', mouseoutListener, {passive: true});

                mouseoverTimer = setTimeout(() => {
                    preload(linkElement);
                    mouseoverTimer = undefined;
                }, delayOnHover);
            }

            function mousedownListener(event) {
                const linkElement = event.target.closest('a');

                if (!isPreloadable(linkElement)) {
                    return;
                }

                preload(linkElement);
            }

            function mouseoutListener(event) {
                if (event.relatedTarget && event.target.closest('a') === event.relatedTarget.closest('a')) {
                    return;
                }

                if (mouseoverTimer) {
                    clearTimeout(mouseoverTimer);
                    mouseoverTimer = undefined;
                }
            }

            function mousedownShortcutListener(event) {
                if (performance.now() - lastTouchTimestamp < DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION) {
                    return;
                }

                const linkElement = event.target.closest('a');

                if (event.which > 1 || event.metaKey || event.ctrlKey) {
                    return;
                }

                if (!linkElement) {
                    return;
                }

                linkElement.addEventListener('click', function (event) {
                    if (event.detail === 1337) {
                        return;
                    }

                    event.preventDefault();
                }, {capture: true, passive: false, once: true});

                const customEvent = new MouseEvent('click', {
                    view: window,
                    bubbles: true,
                    cancelable: true,
                    detail: 1337
                });
                linkElement.dispatchEvent(customEvent);
            }

            function isPreloadable(linkElement) {
                if (!linkElement || !linkElement.href) {
                    return;
                }

                if (util.include(linkElement.href, excludeKeyword)) {
                    if (!util.reg.chrome.test(linkElement.href) &&
                        !util.reg.chromeNew.test(linkElement.href) &&
                        !util.reg.edge.test(linkElement.href) &&
                        !util.reg.edge.test(linkElement.href) &&
                        !util.reg.microsoft.test(linkElement.href)) {
                        return;
                    }
                }

                if (useWhitelist && !('instant' in linkElement.dataset)) {
                    return;
                }

                if (!allowExternalLinks && linkElement.origin !== location.origin && !('instant' in linkElement.dataset)) {
                    return;
                }

                if (!['http:', 'https:'].includes(linkElement.protocol)) {
                    return;
                }

                if (linkElement.protocol === 'http:' && location.protocol === 'https:') {
                    if (linkElement.href.indexOf('http://www.baidu.com/link?url') === 0) {
                        linkElement.href = linkElement.href.replace('http', 'https');
                    } else {
                        return;
                    }
                }
                //下载文件不加速
                if (/\.[a-zA-Z0-9]{0,5}$/i.test(linkElement.href)) {
                    //排除域名,网站扩展名
                    if (!/(com|cn|top|ltd|net|tech|shop|vip|xyz|wang|cloud|online|site|love|art|xin|store|fun|cc|website|press|space|beer|luxe|video|ren|group|fit|yoga|org|pro|ink|biz|info|design|link|work|mobi|kim|pub|name|tv|co|asia|red|live|wiki|gov|life|world|run|show|city|gold|today|plus|cool|icu|company|chat|zone|fans|law|host|center|club|email|fund|social|team|guru|htm|html|php|asp|jsp)$/i.test(linkElement.href)) {
                        return;
                    }
                }

                if (!allowQueryString && linkElement.search && !('instant' in linkElement.dataset)) {
                    return;
                }

                if (linkElement.hash && linkElement.pathname + linkElement.search === location.pathname + location.search) {
                    return;
                }

                if (linkElement.dataset.filename || linkElement.dataset.noInstant) {
                    return;
                }

                return true;
            }

            function preload(linkElement) {
                let url = linkElement.href;

                if (!isOnline()) {
                    return;
                }

                if (prefetches.has(url)) {
                    return;
                }

                if (enableStoreLink) {
                    if (util.reg.chrome.test(url)) {
                        linkElement.href = url.replace("chrome.google.com", "chrome.crxsoso.com");
                    }
                    if (util.reg.chromeNew.test(url)) {
                        linkElement.href = url.replace("chromewebstore.google.com", "chrome.crxsoso.com/webstore");
                    }
                    if (util.reg.edge.test(url)) {
                        linkElement.href = url.replace("microsoftedge.microsoft.com", "microsoftedge.crxsoso.com");
                    }
                    if (util.reg.firefox.test(url)) {
                        linkElement.href = url.replace("addons.mozilla.org", "addons.crxsoso.com");
                    }
                    if (util.reg.microsoft.test(url)) {
                        linkElement.href = url.replace(/(www|apps)\.microsoft\.com/, "apps.crxsoso.com");
                    }
                }

                const prefetcher = document.createElement('link');
                prefetcher.rel = 'prefetch';
                prefetcher.href = url;
                document.head.appendChild(prefetcher);

                prefetches.add(url);

                if (enableAnimation) {
                    linkElement.classList.add("link-instanted");
                }
                if (enableTargetSelf) {
                    linkElement.target = '_self';
                }

                util.setValue('setting_success_times', util.getValue('setting_success_times') + 1);
            }
        },

        addPluginStyle() {
            let style = `
                .instant-popup { font-size: 14px !important; }
                .instant-setting-label { display: flex;align-items: center;justify-content: space-between;padding-top: 15px; }
                .instant-setting-label-col { display: flex;align-items: flex-start;;padding-top: 15px;flex-direction:column }
                .instant-setting-checkbox { width: 16px;height: 16px; }
                .instant-setting-textarea { width: 100%; margin: 14px 0 0; height: 60px; resize: none; border: 1px solid #bbb; box-sizing: border-box; padding: 5px 10px; border-radius: 5px; color: #666; line-height: 1.2; }
                .instant-setting-input { border: 1px solid #bbb; box-sizing: border-box; padding: 5px 10px; border-radius: 5px; width: 100px}
                 @keyframes instantAnminate { from { opacity: 1; } 50% { opacity: 0.4 } to { opacity: 0.9; }}
                .link-instanted { animation: instantAnminate 0.6s 1; animation-fill-mode:forwards }
                .link-instanted * { animation: instantAnminate 0.6s 1; animation-fill-mode:forwards }
            `;

            if (document.head) {
                util.addStyle('swal-pub-style', 'style', GM_getResourceText('swalStyle'));
                util.addStyle('instant-style', 'style', style);
            }

            const headObserver = new MutationObserver(() => {
                util.addStyle('swal-pub-style', 'style', GM_getResourceText('swalStyle'));
                util.addStyle('instant-style', 'style', style);
            });
            headObserver.observe(document.head, {childList: true, subtree: true});
        },

        init() {
            this.initValue();
            this.addPluginStyle();
            this.registerMenuCommand();
            if (this.inExcludeList()) return;
            this.instantPage();
        }
    };
    main.init();
})();

1 Like

好东西啊

知乎的装了

Mactype助手 字体看的比较顺眼