您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
AI Studio 增强脚本。可自动启用谷歌搜索和"URL 上下文"等功能。
// ==UserScript== // @name AI Studio 增强器 - 自动启用谷歌搜索和 URL 上下文 // @name:en AI Studio Enhancer - Auto-enable Google Search and URL Context // @namespace http://tampermonkey.net/ // @version 1.0 // @description AI Studio 增强脚本。可自动启用谷歌搜索和"URL 上下文"等功能。 // @description:en A script to automatically enable features like Grounding and URL Context in AI Studio. // @author fleey // @match https://aistudio.google.com/* // @grant none // @run-at document-idle // @license MIT // ==/UserScript== (function() { 'use strict'; /** * @class AIStudioEnhancer * @description Encapsulates all logic for observing and interacting with the AI Studio UI. * This class-based approach improves maintainability, scalability, and organization. */ class AIStudioEnhancer { /** * The configuration for the enhancer script. * @private */ config = { // Set to `false` to disable all console logs for a cleaner experience. DEBUG: true, // Debounce delay in milliseconds. Prevents excessive checks during rapid DOM changes. DEBOUNCE_DELAY: 150, // A collection of UI elements to target for automatic activation. // This structure makes it easy to add more targets in the future. TARGETS: [ { name: 'Grounding with Google Search', selector: 'button[aria-label*="Grounding with Google Search"][aria-checked="false"]', }, { name: 'URL Context', selector: 'button[aria-label*="url context"][aria-checked="false"]', }, ], }; /** * The MutationObserver instance watching for DOM changes. * @private */ observer = null; /** * A debounced version of the `processTargets` method for performance optimization. * @private */ debouncedProcessTargets; constructor() { this.debouncedProcessTargets = this.debounce(this.processTargets, this.config.DEBOUNCE_DELAY); this.log('Initializing...'); } /** * A simple logger that respects the DEBUG flag. * @param {...any} args - Arguments to log. */ log(...args) { if (this.config.DEBUG) { console.log('[AI Studio Enhancer] - ai_studio_enhancer_v4.js:70', ...args); } } /** * Creates a debounced function that delays invoking `func` until after `wait` milliseconds * have elapsed since the last time the debounced function was invoked. * @param {Function} func The function to debounce. * @param {number} wait The number of milliseconds to delay. * @returns {Function} Returns the new debounced function. */ debounce(func, wait) { let timeout; return (...args) => { clearTimeout(timeout); timeout = setTimeout(() => func.apply(this, args), wait); }; } /** * The core logic to find and click target buttons. * It iterates through configured targets and activates them if found. */ processTargets() { this.log('Running target processing...'); for (const target of this.config.TARGETS) { // Query the DOM for each specific target. const button = document.querySelector(target.selector); if (button) { this.log(`Target found: "${target.name}". Attempting to enable...`); button.click(); this.log(`Successfully enabled "${target.name}".`); } } } /** * The callback function for the MutationObserver. * This is optimized to only check relevant node additions. * @param {MutationRecord[]} mutationsList - A list of mutations that occurred. */ handleMutations = (mutationsList) => { let relevantChangeDetected = false; for (const mutation of mutationsList) { // We are only interested in mutations where new nodes are added. if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { // This is a crucial optimization: // Instead of re-querying the whole document on any change, // we check if the *newly added nodes* could contain our targets. // A simple check is to see if any added node is an Element. for (const node of mutation.addedNodes) { if (node.nodeType === Node.ELEMENT_NODE) { relevantChangeDetected = true; break; } } } if(relevantChangeDetected) break; } if(relevantChangeDetected) { this.log('Relevant DOM change detected. Debouncing target processing.'); this.debouncedProcessTargets(); } }; /** * Starts the script by performing an initial check and setting up the observer. */ start() { // Perform an initial check shortly after the script loads. // requestAnimationFrame is often smoother than a fixed setTimeout. requestAnimationFrame(() => this.processTargets()); // Set up the observer to watch for dynamic content loading. this.observer = new MutationObserver(this.handleMutations); this.observer.observe(document.body, { childList: true, subtree: true, }); this.log('Observer is now active. Waiting for DOM changes.'); } /** * Disconnects the observer to clean up resources. */ stop() { if (this.observer) { this.observer.disconnect(); this.log('Observer disconnected.'); } } } // --- SCRIPT EXECUTION --- const enhancer = new AIStudioEnhancer(); enhancer.start(); })();