您需要先安装一个扩展,例如 篡改猴、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 360's bot.n.cn // @namespace http://tampermonkey.net/ // @version 0.0.1 // @description Adds a "Copy" button to chat message elements to easily copy their content. // @author aspen138 // @match *://bot.n.cn/* // @grant none // @run-at document-end // @icon https://p1.ssl.qhimg.com//t11098f6bcd26caa77d8aa4d2fb.png // @license MIT // ==/UserScript== (function() { 'use strict'; // Update these if class names change const MESSAGE_CONTENT_CLASS = 'UserMessage-module__container--cAvvK'; const CHAT_MESSAGE_CONTENT_CLASS = 'ChatMessage-module__content--MYneF'; const NEW_MESSAGE_SELECTOR = '.max-w-\\[80\\%\\].rounded-\\[16px\\].px-\\[16px\\].py-\\[10px\\].text-white.text-\\[15px\\].leading-\\[22px\\].whitespace-pre-line.break-all.overflow-x-hidden'; function createCopyButton() { const button = document.createElement('button'); button.innerText = 'Copy'; button.classList.add('copy-button'); button.style.position = 'sticky'; button.style.top = '10px'; button.style.right = '10px'; button.style.backgroundColor = '#4CAF50'; button.style.color = '#fff'; button.style.border = 'none'; button.style.borderRadius = '4px'; button.style.padding = '5px 10px'; button.style.cursor = 'pointer'; button.style.fontSize = '0.9em'; button.style.zIndex = '1000'; button.style.boxShadow = '0 2px 6px rgba(0,0,0,0.2)'; button.style.marginLeft = 'auto'; button.style.float = 'right'; button.style.display = 'inline-block'; button.addEventListener('mouseenter', () => { button.style.backgroundColor = '#45a049'; }); button.addEventListener('mouseleave', () => { button.style.backgroundColor = '#4CAF50'; }); return button; } function addCopyButton(element) { if (element.querySelector('.copy-button')) return; const isNewMessage = element.matches(NEW_MESSAGE_SELECTOR); const contentElement = isNewMessage ? element : element.querySelector(`.${MESSAGE_CONTENT_CLASS}`); if (!contentElement) return; element.style.position = 'relative'; element.style.display = 'block'; const copyButton = createCopyButton(); copyButton.addEventListener('click', () => { const textToCopy = contentElement.innerText.trim().replace(/Copy(?=[^Copy]*$)/, ""); navigator.clipboard.writeText(textToCopy).then(() => { copyButton.innerText = 'Copied!'; copyButton.style.backgroundColor = '#388E3C'; setTimeout(() => { copyButton.innerText = 'Copy'; copyButton.style.backgroundColor = '#4CAF50'; }, 2000); }).catch(err => { console.error('Failed to copy text: ', err); }); }); element.appendChild(copyButton); } function processExistingMessages() { // Process original chat messages document.querySelectorAll(`.${CHAT_MESSAGE_CONTENT_CLASS}`).forEach(addCopyButton); // Process new gradient messages document.querySelectorAll(NEW_MESSAGE_SELECTOR).forEach(addCopyButton); } function observeNewMessages() { const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { if (mutation.type === 'childList') { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { // Check for both message types if (node.matches(`.${CHAT_MESSAGE_CONTENT_CLASS}, ${NEW_MESSAGE_SELECTOR}`)) { addCopyButton(node); } // Check nested elements node.querySelectorAll(`.${CHAT_MESSAGE_CONTENT_CLASS}, ${NEW_MESSAGE_SELECTOR}`).forEach(addCopyButton); } }); } } }); observer.observe(document.body, { childList: true, subtree: true }); } function init() { processExistingMessages(); observeNewMessages(); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();