您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
One-click clipboard quote → GitHub Gist, with keyword highlighting
当前为
// ==UserScript== // @name Clip-to-Gist // @name:zh-CN Clip-to-Gist 金句剪贴脚本(v2) // @namespace https://github.com/yourusername // @version 2.0 // @description One-click clipboard quote → GitHub Gist, with keyword highlighting // @description:zh-CN 一键剪贴板金句并上传至 GitHub Gist,支持关键词标注和高亮 // @author Your Name // @match *://*/* // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_registerMenuCommand // @license MIT // ==/UserScript== (function() { 'use strict'; // 注册(不可用)菜单:配置 Gist 参数 GM_registerMenuCommand('配置 Gist 参数', openConfigModal); // 注入右下角触发按钮 const trigger = document.createElement('div'); trigger.id = 'clip2gist-trigger'; trigger.textContent = '📝'; document.body.appendChild(trigger); // 样式 GM_addStyle(` #clip2gist-trigger { position: fixed; bottom: 20px; right: 20px; width: 40px; height: 40px; line-height: 40px; background: #4CAF50; color: #fff; text-align: center; border-radius: 50%; cursor: pointer; z-index: 9999; font-size: 24px; } .clip2gist-mask { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 10000; } .clip2gist-dialog { background: #fff; padding: 20px; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 2px 10px rgba(0,0,0,0.3); } .clip2gist-dialog input { width: 100%; padding: 6px; margin-top: 4px; margin-bottom: 12px; box-sizing: border-box; font-size: 14px; } .clip2gist-dialog button { margin-left: 8px; padding: 6px 12px; font-size: 14px; } .clip2gist-word { display: inline-block; margin: 2px; padding: 4px 6px; border: 1px solid #ccc; border-radius: 4px; cursor: pointer; user-select: none; } .clip2gist-word.selected { background: #ffeb3b; border-color: #f1c40f; } #clip2gist-preview { margin-top: 12px; padding: 8px; border: 1px solid #ddd; min-height: 40px; font-family: monospace; } `); trigger.addEventListener('click', mainFlow); async function mainFlow() { let text = ''; try { text = await navigator.clipboard.readText(); } catch (e) { return alert('请在 HTTPS 环境并授权剪贴板访问'); } if (!text.trim()) return alert('剪贴板内容为空'); showEditDialog(text.trim()); } function showEditDialog(rawText) { const mask = document.createElement('div'); mask.className = 'clip2gist-mask'; const dlg = document.createElement('div'); dlg.className = 'clip2gist-dialog'; // 词块化 const wordContainer = document.createElement('div'); rawText.split(/\s+/).forEach(w => { const sp = document.createElement('span'); sp.className = 'clip2gist-word'; sp.textContent = w; sp.addEventListener('click', () => { sp.classList.toggle('selected'); updatePreview(); }); wordContainer.appendChild(sp); }); dlg.appendChild(wordContainer); // 预览区 const preview = document.createElement('div'); preview.id = 'clip2gist-preview'; dlg.appendChild(preview); // 按钮行 const btnRow = document.createElement('div'); const cancelBtn = document.createElement('button'); cancelBtn.textContent = '取消'; cancelBtn.addEventListener('click', () => document.body.removeChild(mask)); const configBtn = document.createElement('button'); configBtn.textContent = '配置'; configBtn.addEventListener('click', openConfigModal); const confirmBtn = document.createElement('button'); confirmBtn.textContent = '确认'; confirmBtn.addEventListener('click', onConfirm); btnRow.append(cancelBtn, configBtn, confirmBtn); dlg.appendChild(btnRow); mask.appendChild(dlg); document.body.appendChild(mask); updatePreview(); function updatePreview() { const spans = Array.from(wordContainer.children); const final = []; for (let i = 0; i < spans.length;) { if (spans[i].classList.contains('selected')) { const group = [spans[i].textContent]; let j = i + 1; while (j < spans.length && spans[j].classList.contains('selected')) { group.push(spans[j].textContent); j++; } final.push(`{${group.join(' ')}}`); i = j; } else { final.push(spans[i].textContent); i++; } } preview.textContent = final.join(' '); } async function onConfirm() { const gistId = await GM_getValue('gistId'); const token = await GM_getValue('githubToken'); if (!gistId || !token) { return alert('请先通过“配置 Gist 参数”填写 Gist ID 与 Token'); } const content = preview.textContent; GM_xmlhttpRequest({ method: 'GET', url: `https://api.github.com/gists/${gistId}`, headers: { Authorization: `token ${token}` }, onload(resp1) { if (resp1.status !== 200) return alert('拉取 Gist 失败'); const data = JSON.parse(resp1.responseText); const fname = Object.keys(data.files)[0]; const old = data.files[fname].content; const updated = `\n\n----\n${content}` + old; GM_xmlhttpRequest({ method: 'PATCH', url: `https://api.github.com/gists/${gistId}`, headers: { Authorization: `token ${token}`, 'Content-Type': 'application/json' }, data: JSON.stringify({ files: { [fname]: { content: updated } } }), onload(resp2) { if (resp2.status === 200) { alert('上传成功 🎉'); document.body.removeChild(mask); } else { alert('上传失败:' + resp2.status); } } }); } }); } } function openConfigModal() { const mask = document.createElement('div'); mask.className = 'clip2gist-mask'; const dlg = document.createElement('div'); dlg.className = 'clip2gist-dialog'; const idLabel = document.createElement('label'); idLabel.textContent = 'Gist ID:'; const idInput = document.createElement('input'); idInput.value = GM_getValue('gistId', ''); const tkLabel = document.createElement('label'); tkLabel.textContent = 'GitHub Token:'; const tkInput = document.createElement('input'); tkInput.value = GM_getValue('githubToken', ''); dlg.append(idLabel, idInput, tkLabel, tkInput); const saveBtn = document.createElement('button'); saveBtn.textContent = '保存'; saveBtn.addEventListener('click', () => { GM_setValue('gistId', idInput.value.trim()); GM_setValue('githubToken', tkInput.value.trim()); alert('配置已保存'); document.body.removeChild(mask); }); const cancelBtn2 = document.createElement('button'); cancelBtn2.textContent = '取消'; cancelBtn2.addEventListener('click', () => document.body.removeChild(mask)); dlg.append(saveBtn, cancelBtn2); mask.appendChild(dlg); document.body.appendChild(mask); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址