您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a "Copy" button to chat message elements to easily copy their content.
当前为
// ==UserScript== // @name Add Copy Button to Chat Messages on Gtihub Copilot web page // @namespace http://tampermonkey.net/ // @version 1.0 // @description Adds a "Copy" button to chat message elements to easily copy their content. // @author aspen138 // @match *://github.com/copilot/c/* // @match *://github.com/copilot/ // @match *://github.com/copilot/* // @grant none // @run-at document-end // @license MIT // ==/UserScript== (function() { 'use strict'; // Configuration: Update these class names if they change const MESSAGE_CONTENT_CLASS = 'UserMessage-module__container--cAvvK'; const CHAT_MESSAGE_CONTENT_CLASS = 'ChatMessage-module__content--MYneF'; /** * Creates and returns a copy button element. * @returns {HTMLButtonElement} The copy button. */ function createCopyButton() { const button = document.createElement('button'); button.innerText = 'Copy'; button.style.marginLeft = '10px'; button.style.padding = '5px 10px'; button.style.cursor = 'pointer'; button.style.fontSize = '0.9em'; // Optional: Add more styles to match your site's design return button; } /** * Adds a copy button to a chat message element. * @param {HTMLElement} messageElement The chat message element. */ function addCopyButton(messageElement) { // Prevent adding multiple buttons to the same message if (messageElement.querySelector('.copy-button')) { return; } const messageContent = messageElement.querySelector(`.${MESSAGE_CONTENT_CLASS}`); if (!messageContent) return; const copyButton = createCopyButton(); copyButton.classList.add('copy-button'); // Event listener for the copy action copyButton.addEventListener('click', () => { const textToCopy = messageContent.innerText.trim(); navigator.clipboard.writeText(textToCopy).then(() => { // Optional: Provide feedback to the user copyButton.innerText = 'Copied!'; setTimeout(() => { copyButton.innerText = 'Copy'; }, 2000); }).catch(err => { console.error('Failed to copy text: ', err); }); }); // Append the copy button to the message element // Adjust the append location as needed messageElement.appendChild(copyButton); } /** * Processes all existing chat message elements on the page. */ function processExistingMessages() { const messageElements = document.querySelectorAll(`.${CHAT_MESSAGE_CONTENT_CLASS}`); messageElements.forEach(messageElement => { addCopyButton(messageElement); }); } /** * Sets up a MutationObserver to watch for new chat messages being added to the DOM. */ function observeNewMessages() { const targetNode = document.body; const config = { childList: true, subtree: true }; const callback = function(mutationsList) { for (const mutation of mutationsList) { if (mutation.type === 'childList') { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { // Check if the added node is a chat message if (node.classList && node.classList.contains(CHAT_MESSAGE_CONTENT_CLASS)) { addCopyButton(node); } // Also check within the subtree of the added node const nestedMessages = node.querySelectorAll(`.${CHAT_MESSAGE_CONTENT_CLASS}`); nestedMessages.forEach(nestedNode => { addCopyButton(nestedNode); }); } }); } } }; const observer = new MutationObserver(callback); observer.observe(targetNode, config); } /** * Initializes the script by processing existing messages and setting up observers. */ function init() { processExistingMessages(); observeNewMessages(); } // Wait for the DOM to be fully loaded before initializing if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址