您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds copy button and double-click functionality to extract formatted text from asta.allen.ai
// ==UserScript== // @name Asta copier // @namespace https://violentmonkey.github.io/ // @version 1.7 // @description Adds copy button and double-click functionality to extract formatted text from asta.allen.ai // @author Bui Quoc Dung // @match *://asta.allen.ai/* // @grant none // ==/UserScript== (function() { 'use strict'; const ACCORDION_SUMMARY_SELECTOR = '.MuiAccordionSummary-root'; const ACCORDION_ROOT_SELECTOR = '.MuiAccordion-root'; const ACCORDION_HEADING_SELECTOR = '.MuiAccordion-heading'; const ACCORDION_BODY_SELECTOR = '.MuiTypography-body1'; const CITATION_SELECTOR = '.MuiChip-root'; const PARAGRAPH_SELECTOR = '.MuiAccordionDetails-root'; const COPY_BUTTON_CLASS = 'MuiButtonBase-root MuiIconButton-root MuiIconButton-sizeSmall'; function findDisclaimerButton() { const buttons = document.querySelectorAll('button'); for (let button of buttons) { if (button.textContent.includes('Disclaimer')) { return button; } } return null; } function expandSections() { console.log("Expanding all sections..."); document.querySelectorAll(ACCORDION_SUMMARY_SELECTOR).forEach(btn => btn.click()); } function copyToClipboard(text) { let tempContainer = document.createElement('div'); tempContainer.innerHTML = text; document.body.appendChild(tempContainer); let range = document.createRange(); range.selectNode(tempContainer); let selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); try { document.execCommand('copy'); console.log("Copied formatted text."); } catch (err) { console.error("Copy failed", err); } selection.removeAllRanges(); document.body.removeChild(tempContainer); } function processText(paragraphElement, includeHeading = true) { let tempDiv = paragraphElement.cloneNode(true); let paragraphText = tempDiv.innerHTML; tempDiv.querySelectorAll(CITATION_SELECTOR).forEach(citation => { let linkElement = citation.closest('a'); if (linkElement) { let hyperlink = linkElement.href; let citationText = citation.innerText; let formattedCitation = `<a href="${hyperlink}" target="_blank">${citationText}</a>`; paragraphText = paragraphText.replace(citation.outerHTML, formattedCitation); } }); paragraphText = paragraphText.replace(/<div[^>]*>/g, ' ') .replace(/<\/div>/g, '') .replace(/\s+/g, ' '); paragraphText = paragraphText .replace(/Is this section helpful\? /g, "") .replace(/Is this table helpful\? /g, ""); if (includeHeading) { let headingText = ""; let intermediateText = ""; let accordion = paragraphElement.closest(ACCORDION_ROOT_SELECTOR); if (accordion) { let headingElement = accordion.querySelector(ACCORDION_HEADING_SELECTOR); if (headingElement) { headingText = `<strong><u>${headingElement.innerText.trim()}</u></strong>`.trim(); } let intermediateElement = accordion.querySelector(ACCORDION_BODY_SELECTOR); if (intermediateElement) { intermediateText = intermediateElement.innerText.trim(); } if (headingText) { let prefix = headingText + ':\n'; if (intermediateText) { prefix += intermediateText + '\n'; } paragraphText = prefix + paragraphText; } } } return paragraphText; } function closeMenuIfOpen() { const collapseBtn = document.querySelector('button[data-track-name="thread_bar__collapse_btn"]'); if (!collapseBtn) return; const closeIcon = collapseBtn.querySelector('svg[data-testid="CloseIcon"]'); if (closeIcon) { collapseBtn.click(); console.log("Closed menu panel before copying."); } else { console.log("Menu panel already closed."); } } function addCopyButton() { let targetButton = findDisclaimerButton(); if (!targetButton) { return; } if (document.querySelector('#custom-copy-button')) { return; } let copyButton = document.createElement('button'); copyButton.id = 'custom-copy-button'; copyButton.className = COPY_BUTTON_CLASS; copyButton.style.marginLeft = '10px'; copyButton.style.color = 'black'; copyButton.title = "Copy Text"; copyButton.textContent = "Copy"; targetButton.parentNode.insertBefore(copyButton, targetButton.nextSibling); copyButton.addEventListener('click', () => { console.log("Copy button clicked!"); copyButton.textContent = "Coping"; // đóng panel nếu nó đang mở closeMenuIfOpen(); expandSections(); setTimeout(() => { let copiedText = extractAllText(); copyToClipboard(copiedText); copyButton.textContent = "Copy"; }, 1500); }); } function extractAllText() { let paragraphs = document.querySelectorAll(PARAGRAPH_SELECTOR); let copiedText = ""; paragraphs = Array.from(paragraphs).slice(0, -1); paragraphs.forEach(paragraph => { let processedText = processText(paragraph, true); copiedText += processedText + '\n\n'; }); return copiedText; } function handleDoubleClick(event) { const targetDiv = event.target.closest(PARAGRAPH_SELECTOR); if (!targetDiv) return; closeMenuIfOpen(); let accordion = targetDiv.closest(ACCORDION_ROOT_SELECTOR); if (accordion) { let button = accordion.querySelector(ACCORDION_SUMMARY_SELECTOR); if (button) { button.click(); } } setTimeout(() => { let textContent = processText(targetDiv, true); copyToClipboard(textContent); }, 500); } function initialize() { const observer = new MutationObserver(() => { addCopyButton(); }); observer.observe(document.body, { childList: true, subtree: true }); document.body.addEventListener('dblclick', handleDoubleClick); setTimeout(addCopyButton, 2000); } initialize(); })();