// ==UserScript==
// @name 贴吧Grok链接转换
// @namespace http://tampermonkey.net/
// @version 1.0.0
// @description 自动将百度贴吧中的Grok分享代码转换为可点击的链接,点击后变灰,有导出记录功能
// @author Donny
// @match https://tieba.baidu.com/*
// @grant none
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
console.log('[Grok Link] 脚本已加载');
// 存储键名
const STORAGE_KEY = 'grok_visited_uuids';
// 获取已访问的UUID列表
function getVisitedUuids() {
try {
const data = localStorage.getItem(STORAGE_KEY);
return data ? JSON.parse(data) : [];
} catch (e) {
console.error('[Grok Link] 读取localStorage失败:', e);
return [];
}
}
// 标记UUID为已访问
function markAsVisited(uuid) {
try {
const visited = getVisitedUuids();
if (!visited.includes(uuid)) {
visited.push(uuid);
localStorage.setItem(STORAGE_KEY, JSON.stringify(visited));
console.log('[Grok Link] ✓ 标记为已访问:', uuid);
}
// 更新页面上所有相同的UUID链接
updateAllLinks(uuid);
} catch (e) {
console.error('[Grok Link] 写入localStorage失败:', e);
}
}
// 更新页面上所有相同UUID的链接样式
function updateAllLinks(uuid) {
const links = document.querySelectorAll(`[data-uuid="${uuid}"]`);
console.log('[Grok Link] 更新链接样式:', uuid, '找到', links.length, '个链接');
links.forEach(link => {
link.style.color = '#999';
link.style.borderBottom = '1px dotted #999';
});
}
// 检查UUID是否已访问
function isVisited(uuid) {
const visited = getVisitedUuids();
return visited.includes(uuid);
}
// 获取链接样式
function getLinkStyle(uuid) {
if (isVisited(uuid)) {
return 'color: #999; text-decoration: none; border-bottom: 1px dotted #999;';
}
return 'color: #4dabf7; text-decoration: none; border-bottom: 1px dotted #4dabf7;';
}
// 匹配 UUID 格式,包括前面的各种前缀
const uuidPattern = /([a-z]*gine\/post\/|\/post\/|\/|\/post|)?([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(\?[^<\s]*)?/gi;
function convertLinks(text) {
// 匹配并转换UUID
text = text.replace(uuidPattern, function(match, prefix, uuid, query) {
// 如果没有匹配到UUID,返回原文本
if (!uuid) {
return match;
}
const fullQuery = query || '';
const fullUuid = uuid + fullQuery;
const url = 'https://grok.com/imagine/post/' + fullUuid;
const style = getLinkStyle(uuid);
// 返回纯UUID链接,不显示前缀
return `${uuid}`;
});
return text;
}
function processNode(node) {
// 只处理文本节点
if (node.nodeType === Node.TEXT_NODE) {
const text = node.textContent;
const converted = convertLinks(text);
if (converted !== text) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = converted;
const fragment = document.createDocumentFragment();
while (tempDiv.firstChild) {
fragment.appendChild(tempDiv.firstChild);
}
node.parentNode.replaceChild(fragment, node);
}
return;
}
// 跳过已经处理过的元素(如 script, style, noscript)
if (node.nodeType === Node.ELEMENT_NODE) {
const tagName = node.tagName.toLowerCase();
if (['script', 'style', 'noscript', 'a', 'code', 'pre'].includes(tagName)) {
return;
}
// 递归处理子节点
const childNodes = Array.from(node.childNodes);
childNodes.forEach(processNode);
}
}
function observeChanges() {
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
mutation.addedNodes.forEach(function(node) {
processNode(node);
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
// 使用事件委托处理点击事件
document.addEventListener('click', function(e) {
if (e.target.classList.contains('grok-uuid-link')) {
const uuid = e.target.getAttribute('data-uuid');
console.log('[Grok Link] ✓ 链接被点击:', uuid);
markAsVisited(uuid);
}
});
// 导出已访问的UUID列表为HTML
function exportVisitedUuids() {
try {
const visited = getVisitedUuids();
const exportDate = new Date().toLocaleString('zh-CN');
let html = `
Grok 已访问链接列表
Grok 已访问链接列表 ${visited.length} 个
导出时间: ${exportDate}
`;
visited.forEach(uuid => {
html += `
${uuid}\n`;
});
html += `
`;
const blob = new Blob([html], { type: 'text/html;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `grok-visited-uuids-${new Date().toISOString().slice(0, 10)}.html`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
console.log('[Grok Link] ✓ 导出成功,共', visited.length, '个UUID');
alert(`导出成功!共 ${visited.length} 个可点击的链接`);
} catch (e) {
console.error('[Grok Link] 导出失败:', e);
alert('导出失败,请查看控制台了解详情');
}
}
// 清空已访问的UUID列表
function clearVisitedUuids() {
if (confirm('确定要清空所有已访问的 UUID 记录吗?此操作不可恢复!')) {
try {
localStorage.removeItem(STORAGE_KEY);
console.log('[Grok Link] ✓ 已清空所有记录');
alert('已清空所有记录,刷新页面后生效');
} catch (e) {
console.error('[Grok Link] 清空失败:', e);
alert('清空失败,请查看控制台了解详情');
}
}
}
// 删除单个UUID记录
function deleteUuid(uuid) {
if (confirm(`确定要删除记录 "${uuid}" 吗?`)) {
try {
const visited = getVisitedUuids();
const index = visited.indexOf(uuid);
if (index > -1) {
visited.splice(index, 1);
localStorage.setItem(STORAGE_KEY, JSON.stringify(visited));
console.log('[Grok Link] ✓ 已删除记录:', uuid);
// 更新弹窗列表和控制面板计数
updateRecordsModal();
updateVisitCount();
}
} catch (e) {
console.error('[Grok Link] 删除记录失败:', e);
alert('删除记录失败,请查看控制台了解详情');
}
}
}
// 打开记录管理弹窗
function openRecordsModal() {
// 检查是否已存在弹窗
if (document.getElementById('grok-records-modal')) {
return;
}
const modal = document.createElement('div');
modal.id = 'grok-records-modal';
modal.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 100000;
display: flex;
justify-content: center;
align-items: center;
`;
const modalContent = document.createElement('div');
modalContent.style.cssText = `
background: white;
border-radius: 12px;
width: 600px;
max-width: 90%;
max-height: 80vh;
display: flex;
flex-direction: column;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
`;
const modalHeader = document.createElement('div');
modalHeader.style.cssText = `
padding: 20px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
`;
modalHeader.innerHTML = `
已访问记录管理
×
`;
const modalBody = document.createElement('div');
modalBody.id = 'grok-records-list';
modalBody.style.cssText = `
padding: 20px;
overflow-y: auto;
flex: 1;
`;
const modalFooter = document.createElement('div');
modalFooter.style.cssText = `
padding: 15px 20px;
border-top: 1px solid #eee;
display: flex;
justify-content: flex-end;
gap: 10px;
`;
const closeBtn = document.createElement('button');
closeBtn.textContent = '关闭';
closeBtn.style.cssText = `
padding: 8px 20px;
background: #999;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
`;
closeBtn.onmouseover = function() { this.style.background = '#888'; };
closeBtn.onmouseout = function() { this.style.background = '#999'; };
closeBtn.onclick = function() {
document.body.removeChild(modal);
};
modalFooter.appendChild(closeBtn);
modalContent.appendChild(modalHeader);
modalContent.appendChild(modalBody);
modalContent.appendChild(modalFooter);
modal.appendChild(modalContent);
document.body.appendChild(modal);
// 关闭按钮
document.getElementById('grok-modal-close').onclick = function() {
document.body.removeChild(modal);
};
// 点击背景关闭
modal.onclick = function(e) {
if (e.target === modal) {
document.body.removeChild(modal);
}
};
// 更新记录列表
updateRecordsModal();
}
// 更新记录弹窗内容
function updateRecordsModal() {
const modalBody = document.getElementById('grok-records-list');
if (!modalBody) return;
const visited = getVisitedUuids();
if (visited.length === 0) {
modalBody.innerHTML = '暂无记录
';
return;
}
let html = '共 ' + visited.length + ' 条记录
';
html += '';
visited.forEach((uuid, index) => {
html += `
`;
});
html += '
';
modalBody.innerHTML = html;
}
// 创建控制面板
function createControlPanel() {
// 检查是否已存在
if (document.getElementById('grok-control-panel')) {
return;
}
const panel = document.createElement('div');
panel.id = 'grok-control-panel';
panel.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: white;
border: 1px solid #ddd;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
z-index: 99999;
font-family: Arial, sans-serif;
font-size: 14px;
min-width: 200px;
`;
const header = document.createElement('div');
header.style.cssText = `
font-weight: bold;
margin-bottom: 10px;
color: #333;
display: flex;
justify-content: space-between;
align-items: center;
`;
header.innerHTML = `
Grok 链接管理
×
`;
const info = document.createElement('div');
info.id = 'grok-visit-count';
info.style.cssText = `
margin-bottom: 10px;
color: #666;
font-size: 12px;
`;
info.textContent = '已访问: 0 个';
const viewBtn = document.createElement('button');
viewBtn.textContent = '查看记录';
viewBtn.style.cssText = `
width: 100%;
padding: 8px;
margin-bottom: 8px;
background: #6c757d;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
`;
viewBtn.onmouseover = function() { this.style.background = '#5a6268'; };
viewBtn.onmouseout = function() { this.style.background = '#6c757d'; };
viewBtn.onclick = openRecordsModal;
const exportBtn = document.createElement('button');
exportBtn.textContent = '导出记录';
exportBtn.style.cssText = `
width: 100%;
padding: 8px;
margin-bottom: 8px;
background: #4dabf7;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
`;
exportBtn.onmouseover = function() { this.style.background = '#3b9cdb'; };
exportBtn.onmouseout = function() { this.style.background = '#4dabf7'; };
exportBtn.onclick = exportVisitedUuids;
const clearBtn = document.createElement('button');
clearBtn.textContent = '清空记录';
clearBtn.style.cssText = `
width: 100%;
padding: 8px;
background: #ff6b6b;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
`;
clearBtn.onmouseover = function() { this.style.background = '#e55a5a'; };
clearBtn.onmouseout = function() { this.style.background = '#ff6b6b'; };
clearBtn.onclick = clearVisitedUuids;
panel.appendChild(header);
panel.appendChild(info);
panel.appendChild(viewBtn);
panel.appendChild(exportBtn);
panel.appendChild(clearBtn);
document.body.appendChild(panel);
// 关闭按钮
document.getElementById('grok-panel-close').onclick = function() {
panel.style.display = 'none';
};
// 更新计数
updateVisitCount();
}
// 将删除函数暴露到全局作用域
window.grokDeleteUuid = deleteUuid;
// 更新访问计数显示
function updateVisitCount() {
const info = document.getElementById('grok-visit-count');
if (info) {
const visited = getVisitedUuids();
info.textContent = `已访问: ${visited.length} 个`;
}
}
// 添加快捷键打开控制面板
document.addEventListener('keydown', function(e) {
if (e.ctrlKey && e.shiftKey && e.key === 'G') {
e.preventDefault();
const panel = document.getElementById('grok-control-panel');
if (panel) {
panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
} else {
createControlPanel();
}
}
});
// 初始化:处理当前页面内容
function init() {
// 等待页面完全加载
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
processNode(document.body);
observeChanges();
createControlPanel();
});
} else {
processNode(document.body);
observeChanges();
createControlPanel();
}
}
init();
})();