// ==UserScript== // @name 复制格式转换 (Markdown) // @namespace http://tampermonkey.net/ // @version 1.0 // @description 选中内容后,按钮智能显示在右上角,点击按钮自动复制为完整的 Markdown 格式。 // @author KiwiFruit // @match *://*/* // @grant GM_setClipboard // @license MIT // @downloadURL none // ==/UserScript== (function () { 'use strict'; // 创建浮动按钮 function createFloatingButton() { const button = document.createElement('button'); button.id = 'markdownCopyButton'; button.innerText = '复制为 Markdown 格式'; button.style.position = 'fixed'; button.style.top = '20px'; // 固定在右上角 button.style.right = '20px'; // 固定在右上角 button.style.padding = '10px 20px'; button.style.backgroundColor = '#007bff'; button.style.color = '#fff'; button.style.border = 'none'; button.style.borderRadius = '5px'; button.style.cursor = 'pointer'; button.style.zIndex = '9999'; button.style.display = 'none'; // 默认隐藏 button.style.boxShadow = '0 4px 6px rgba(0,0,0,0.1)'; document.body.appendChild(button); return button; } let floatingButton = createFloatingButton(); // 显示浮动按钮 function showFloatingButton() { floatingButton.style.display = 'block'; } // 隐藏浮动按钮 function hideFloatingButton() { floatingButton.style.display = 'none'; } // 提取选中内容 function extractSelectedContent(range) { const fragment = range.cloneContents(); // 克隆选中的 DOM 内容 const tempDiv = document.createElement('div'); tempDiv.appendChild(fragment); // 提取文本内容 const text = tempDiv.innerText.trim(); // 提取图片 const images = Array.from(tempDiv.querySelectorAll('img')).map(img => ({ src: img.src, alt: img.alt || "Image", })); // 提取链接 const links = Array.from(tempDiv.querySelectorAll('a')).map(a => ({ text: a.innerText.trim() || "Link", href: a.href, })); return { text, images, links }; } // 转换为 Markdown 格式 function convertToMarkdown(content) { let markdown = ''; // 添加文本内容 if (content.text) { markdown += `${content.text} `; } // 添加图片 content.images.forEach(image => { markdown += `![${image.alt}](${image.src}) `; }); // 添加链接 content.links.forEach(link => { markdown += `[${link.text}](${link.href}) `; }); return markdown.trim(); } // 复制到剪贴板 async function copyToClipboard(text) { try { if (typeof GM_setClipboard === 'function') { GM_setClipboard(text); // 使用油猴的剪贴板 API return true; // 成功 } else { await navigator.clipboard.writeText(text); console.log('Markdown 已复制到剪贴板'); return true; // 成功 } } catch (err) { console.error('复制失败:', err); return false; // 失败 } } // 显示提示信息 function showToast(message) { const toast = document.createElement('div'); toast.style.position = 'fixed'; toast.style.bottom = '20px'; toast.style.right = '20px'; toast.style.padding = '10px 20px'; toast.style.backgroundColor = '#333'; toast.style.color = '#fff'; toast.style.borderRadius = '5px'; toast.style.zIndex = '9999'; toast.style.boxShadow = '0 4px 6px rgba(0,0,0,0.1)'; toast.innerText = message; document.body.appendChild(toast); // 自动移除提示 setTimeout(() => { toast.remove(); }, 2000); // 2秒后消失 } // 监听鼠标释放事件 document.addEventListener('mouseup', handleMouseUp); // 处理鼠标释放事件 function handleMouseUp(event) { const selection = window.getSelection(); if (selection && !selection.isCollapsed) { // 显示按钮 showFloatingButton(); // 绑定按钮点击事件 floatingButton.onclick = async () => { try { const range = selection.getRangeAt(0); const selectedContent = extractSelectedContent(range); const markdownContent = convertToMarkdown(selectedContent); // 复制内容 const success = await copyToClipboard(markdownContent); if (success) { showToast('内容已复制为 Markdown 格式!'); } else { showToast('复制失败,请重试!'); } } catch (err) { console.error('处理内容时出错:', err); showToast('处理内容时出错,请重试!'); } finally { hideFloatingButton(); // 操作完成后隐藏按钮 } }; } else { // 如果没有选中内容,隐藏按钮 hideFloatingButton(); } } // 监听页面点击事件,点击空白区域时隐藏按钮 document.addEventListener('mousedown', (event) => { if (!floatingButton.contains(event.target)) { hideFloatingButton(); } }); })();