// ==UserScript== // @name [MT论坛]“借鉴一下” // @namespace https://github.com/qcxs/mtbbs // @version 2026-05-06 // @description 利用HTML转BBCode工具类解析论坛内容,支持复制、借鉴、分享 // @author 青春向上 // @match *://bbs.binmt.cc/forum.php?*tid=* // @match *://bbs.binmt.cc/*thread-*.html* // @icon https://bbs.binmt.cc/favicon.ico // @grant none // @require https://cdn.jsdelivr.net/gh/qcxs/mtbbs@master/require/Html2BBCode.js // ==/UserScript== (function () { 'use strict'; let isLoading = false; const tid = getTidByUrl(); if (!tid) return; const selectContent = 'div.comiis_messages.comiis_aimg_show.cl'; function getTidByUrl() { const url = new URL(window.location.href); const regex = /thread-(\d+)-/; const match = url.pathname.match(regex); return url.searchParams.get('tid') || (match ? match[1] : null); } // 复制代码块 (function () { const style = document.createElement('style'); style.textContent = ` .comiis_blockcode { position: relative !important; pointer-events: auto !important; } .comiis_blockcode::before { content: "复制"; position: absolute !important; right: 10px !important; top: 1em !important; transform: translateY(-50%) !important; color: #42b983 !important; font-size: 14px !important; font-weight: bold !important; pointer-events: auto !important; } `; document.head.appendChild(style); document.addEventListener('click', (e) => { const codeBlock = e.target.closest('.comiis_blockcode'); if (!codeBlock) return; const codeText = codeBlock.textContent.trim(); previewDia(codeText); }); })(); // 处理元素:添加借鉴、share按钮 function processElement(div) { try { const h2Element = div.querySelector('div.comiis_postli_top.bg_f h2'); const pid = div.id.match(/\d+/)[0]; if (!h2Element.querySelector('span[data-action="reference"]')) { const span = document.createElement('span'); span.dataset.action = "reference"; span.textContent = ' [借鉴一下]'; span.style.cursor = 'pointer'; span.style.color = '#0066cc'; span.style.marginLeft = '8px'; span.style.position = 'relative'; span.style.zIndex = '1'; span.addEventListener('click', async () => { const contentElement = div.querySelector(selectContent); if (contentElement) { if (!isLoading) { const contentHtml = await getLatest(pid, contentElement.innerHTML); const tempDiv = document.createElement('div'); tempDiv.innerHTML = contentHtml; if (Html2BBCode == null) { alert('核心Html2BBCode未加载,请查看require链接是否正确') return; } const bbcode = Html2BBCode.convert(tempDiv); previewDia(bbcode, null, 'ubb代码预览:'); } } }); h2Element.appendChild(span); } const timesElement = div.querySelector('div.comiis_postli_times.bg_f'); if (timesElement) { const bottomZhanSpan = timesElement.querySelector('span.bottom_zhan.y'); if (bottomZhanSpan && !timesElement.querySelector('span[data-action="share"]')) { const shareSpan = document.createElement('span'); shareSpan.dataset.action = "share"; shareSpan.className = 'y'; shareSpan.textContent = 'share'; shareSpan.style.marginLeft = '8px'; shareSpan.addEventListener('click', () => { const link = `https://bbs.binmt.cc/forum.php?mod=redirect&goto=findpost&ptid=${tid}&pid=${pid}`; previewDia(link); }); bottomZhanSpan.parentNode.insertBefore(shareSpan, bottomZhanSpan.nextSibling); } } } catch (error) { console.error('处理元素错误:', error); } } // 初始加载 + 监听动态内容 const targetSelector = 'div.comiis_postli.comiis_list_readimgs.nfqsqi'; document.querySelectorAll(targetSelector).forEach(processElement); const observer = new MutationObserver((mutationsList) => { const processedElements = new WeakSet(); for (const mutation of mutationsList) { if ((mutation.type === 'childList' && mutation.addedNodes.length > 0) || mutation.type === 'characterData') { const currentElement = mutation.type === 'childList' ? mutation.target : mutation.target.parentElement; if (currentElement.matches(targetSelector) && !processedElements.has(currentElement)) { processElement(currentElement); processedElements.add(currentElement); } currentElement.querySelectorAll(targetSelector).forEach(element => { if (!processedElements.has(element)) { processElement(element); processedElements.add(element); } }); } } }); observer.observe(document.body, { childList: true, characterData: true, subtree: true, attributes: false, characterDataOldValue: false }); // 异步获取最新内容 async function getLatest(pid, html) { isLoading = true; try { const response = await fetch(`https://bbs.binmt.cc/forum.php?mod=viewthread&tid=${tid}&viewpid=${pid}&mobile=2&inajax=1`, { method: 'GET', timeout: 3000 }); if (!response.ok) throw new Error('请求失败'); const xmlText = await response.text(); const parser = new DOMParser(); const xmlDoc = parser.parseFromString(xmlText, 'text/xml'); if (xmlDoc.querySelector('parsererror')) throw new Error('XML解析失败'); const root = xmlDoc.lastChild?.firstChild?.nodeValue; if (!root) throw new Error('数据为空'); const tempDiv = document.createElement('div'); tempDiv.innerHTML = root; const content = tempDiv.querySelector(selectContent)?.innerHTML || ''; tempDiv.remove(); return content || html; } catch (e) { console.log(e.message); return html; } finally { isLoading = false; } } // 预览弹窗 function previewDia(text, callback, title) { if (typeof text === 'object') text = JSON.stringify(text) function escapeHtml(unsafe) { return unsafe ? unsafe.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'") : ''; } const mask = document.createElement('div'); mask.style = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:10002'; mask.onclick = () => mask.remove(); const isInputMode = typeof callback === 'function'; mask.innerHTML = `