您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add a button to delete all uploaded files on grok.com/files
// ==UserScript== // @name Grok Delete File Uploads // @namespace nisc // @version 2025.06.08-A // @description Add a button to delete all uploaded files on grok.com/files // @homepageURL https://github.com/nisc/grok-userscripts/ // @author nisc // @match https://grok.com/files // @icon https://grok.com/images/favicon-light.png // @run-at document-end // @grant none // ==/UserScript== (function() { 'use strict'; /** * Configuration object containing all constants used in the script * - Button appearance and behavior settings * - DOM selectors for finding elements * - Timing delays for various operations */ const CONFIG = { BUTTON_ID: 'delete-all-btn', BUTTON_TEXT: 'Delete all files', BUTTON_STYLES: { backgroundColor: 'white', color: 'black', padding: '8px 12px', border: 'none', borderRadius: '8px', cursor: 'pointer', marginBottom: '30px' }, CONTAINER_SELECTOR: '.max-w-\\[50rem\\]', DELETE_BUTTON_SELECTOR: 'button[aria-label="Delete"]', CONFIRM_BUTTON_SELECTOR: 'button[aria-label="Confirm"]', DELAYS: { DELETE_BUTTON: 200, // Time to wait after clicking delete button CONFIRM_BUTTON: 200, // Time to wait after clicking confirm button MODAL_RENDER: 500 // Time to wait for all modals to render } }; /** * Utility function to create a promise that resolves after specified milliseconds * Used to add necessary delays between operations */ const sleep = ms => new Promise(res => setTimeout(res, ms)); /** * Main deletion function that: * 1. Clicks all delete buttons sequentially * 2. Waits for confirmation modals to render * 3. Clicks all confirm buttons sequentially * * Delays are added between operations to ensure UI can keep up */ async function deleteAll() { // First phase: Click all delete buttons const deleteButtons = Array.from(document.querySelectorAll(CONFIG.DELETE_BUTTON_SELECTOR)); if (deleteButtons.length === 0) { return; } for (const btn of deleteButtons) { btn.click(); await sleep(CONFIG.DELAYS.DELETE_BUTTON); } // Wait for all confirmation modals to render await sleep(CONFIG.DELAYS.MODAL_RENDER); // Second phase: Confirm all deletions const confirmButtons = Array.from(document.querySelectorAll(CONFIG.CONFIRM_BUTTON_SELECTOR)); if (confirmButtons.length === 0) { return; } for (const conf of confirmButtons) { conf.click(); await sleep(CONFIG.DELAYS.CONFIRM_BUTTON); } } /** * Creates and adds the "Delete all files" button to the page * Only adds the button if it doesn't already exist */ function addButton() { const container = document.querySelector(CONFIG.CONTAINER_SELECTOR); if (container && !document.getElementById(CONFIG.BUTTON_ID)) { const btn = document.createElement('button'); btn.id = CONFIG.BUTTON_ID; btn.textContent = CONFIG.BUTTON_TEXT; Object.assign(btn.style, CONFIG.BUTTON_STYLES); btn.addEventListener('click', deleteAll); container.insertBefore(btn, container.firstChild); } } // Watch for DOM changes and try to add button when possible // This ensures the button is added even if the container loads dynamically new MutationObserver(addButton).observe(document.body, { childList: true, subtree: true }); // Initial attempt to add the button addButton(); })();