明经复制/下载代码篡改猴扩展
本帖最后由 yangyangyixia 于 2025-11-3 10:28 编辑原贴:http://bbs.mjtd.com/thread-193463-1-1.html
增加了一个下载按钮,直接下载为:代码.lsp
有缺陷,部分代码复制错误,我再研究研究……
修改了一下,不会漏掉代码了。
还是不太完美:下载下来的lsp文件,如果代码中有中文,格式会自动保存为utf8编码,需要手动改为ansi编码,这个我不会优化了
// ==UserScript==
// @name 明经复制/下载代码扩展
// @namespace http://tampermonkey.net/
// @version 2025.10.31.1
// @description复制明经论坛代码区的代码并支持下载为.lsp文件
// @author edata yangyangyixia
// @match *://*.mjtd.com/*
// @icon http://bbs.mjtd.com/favicon.ico
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 复制到剪贴板函数
function copyToClipboard(text) {
return new Promise((resolve, reject) => {
if (navigator.clipboard) {
navigator.clipboard.writeText(text).then(resolve).catch(reject);
} else {
// 兼容旧版浏览器的备用方法
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
try {
const successful = document.execCommand('copy');
document.body.removeChild(textarea);
successful ? resolve() : reject(new Error('复制失败'));
} catch (err) {
document.body.removeChild(textarea);
reject(err);
}
}
});
}
// 下载文件函数
function downloadFile(filename, content) {
const blob = new Blob(, { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// 清理URL对象
setTimeout(() => URL.revokeObjectURL(url), 100);
}
// 转换html转义字符为正常字符
function unescapeHTML(str) {
if (!str) return '';
const entities = {
'nbsp': ' ',
'lt': '<',
'gt': '>',
'amp': '&',
'quot': '"',
'#39': "'",
'#60': '<',
'#62': '>',
'#32': ' ',
'#160': ' '
};
return str.replace(/&([^;]+);/g, function(match, entity) {
if (entity in entities) {
return entities;
}
// 处理数字实体如 < > 等
if (entity.startsWith('#')) {
const code = entity.substring(1);
return String.fromCharCode(parseInt(code));
}
return match;
});
}
// 安全地移除HTML标签(保留代码中的 < > 符号)
function removeTags(str) {
if (!str) return '';
// 先解码所有HTML实体
let decoded = unescapeHTML(str);
// 只移除真正的HTML标签,保留代码中的 < 和 > 符号
// 匹配以 < 开头,后跟字母或/,然后以 > 结尾的标签
return decoded.replace(/<\/?[\s\S]*?>/gi, "");
}
// 移除换行<br />标记
function removeBrTags(str) {
if (!str) return '';
return str.toString().replace(/<br\s*\/?>/gi, "\n");
}
// 清理和格式化代码文本(复制和下载使用相同的格式化函数)
function formatCodeText(text) {
if (!text) return '';
// 先解码HTML实体(包括 < > & nbsp 等)
let formatted = text;
// 多次解码,确保所有HTML实体都被处理
let previous = '';
while (formatted !== previous) {
previous = formatted;
formatted = unescapeHTML(formatted);
}
// 将<br>标签转换为换行符
formatted = removeBrTags(formatted);
// 移除其他HTML标签(但保留代码中的 < > 符号)
formatted = removeTags(formatted);
// 彻底处理所有nbsp和不间断空格,但保留原始空格结构
// 只替换nbsp相关实体,不修改普通空格
formatted = formatted.replace(/ /g, ' ');
formatted = formatted.replace(/\u00A0/g, ' ');
formatted = formatted.replace(/ /g, ' ');
formatted = formatted.replace(/ /g, ' ');
// 清理多余的空行(但保留代码缩进)
formatted = formatted.replace(/\n\s*\n/g, '\n').trim();
return formatted;
}
// 添加样式
function addStyles() {
const style = document.createElement('style');
style.textContent = `
.copy-btn, .download-btn {
display: inline-block;
margin-left: 10px;
padding: 2px 8px;
border-radius: 3px;
font-size: 12px;
cursor: pointer;
transition: background 0.3s;
border: none;
font-family: inherit;
}
.copy-btn {
background: #4CAF50;
color: white;
}
.copy-btn:hover {
background: #45a049;
}
.copy-btn:active {
background: #3d8b40;
}
.copy-btn.copied {
background: #2196F3;
}
.download-btn {
background: #ff9800;
color: white;
}
.download-btn:hover {
background: #f57c00;
}
.download-btn:active {
background: #ef6c00;
}
.download-btn.downloaded {
background: #9c27b0;
}
.code-buttons {
display: inline-block;
margin-left: 10px;
}
`;
document.head.appendChild(style);
}
// 获取代码内容
function getCodeContent(element) {
const textarea = element.querySelector('textarea');
if (textarea) {
// 对于textarea,优先使用value,如果没有则用innerHTML
return textarea.value || textarea.innerHTML;
}
const codeContent = element.querySelector('.jssccodecontent');
if (codeContent) {
return codeContent.innerHTML || codeContent.textContent || codeContent.innerText;
}
return '';
}
// 处理复制操作
async function handleCopy(element, copyBtn) {
const rawText = getCodeContent(element);
const formattedText = formatCodeText(rawText);
try {
if (typeof setCopy === 'function') {
setCopy(formattedText, "代码已复制到剪贴板");
} else {
await copyToClipboard(formattedText);
setCopy(formattedText, "代码已复制到剪贴板");
}
copyBtn.textContent = '复制成功!';
copyBtn.classList.add('copied');
setTimeout(() => {
copyBtn.textContent = '格式复制';
copyBtn.classList.remove('copied');
}, 2000);
} catch (err) {
console.error('复制失败:', err);
copyBtn.textContent = '复制失败';
setTimeout(() => {
copyBtn.textContent = '格式复制';
}, 2000);
}
}
// 处理下载操作
function handleDownload(element, downloadBtn) {
const rawText = getCodeContent(element);
// 使用与复制相同的格式化函数,确保格式一致
const formattedText = formatCodeText(rawText);
if (!formattedText.trim()) {
setCopy(formattedText, "没有可下载的代码内容");
return;
}
const filename = `代码.lsp`;
downloadFile(filename, formattedText);
downloadBtn.textContent = '下载成功!';
downloadBtn.classList.add('downloaded');
setCopy(formattedText, "已下载为代码.lsp");
setTimeout(() => {
downloadBtn.textContent = '下载lsp';
downloadBtn.classList.remove('downloaded');
}, 2000);
}
// 主处理函数 - 添加复制和下载按钮
function addCodeButtons() {
// 获取所有以"mc_code"开头的元素
const elements = [];
let index = 0;
while (true) {
const element = document.getElementById(`mc_code${index}`);
if (!element) break;
elements.push(element);
index++;
}
// 处理每个找到的元素
elements.forEach(element => {
const titleElement = element.querySelector('.jssccodetitle');
if (!titleElement) return;
// 检查是否已添加按钮容器
let buttonsContainer = titleElement.querySelector('.code-buttons');
if (buttonsContainer) return;
// 创建按钮容器
buttonsContainer = document.createElement('span');
buttonsContainer.className = 'code-buttons';
// 创建复制按钮
const copyBtn = document.createElement('button');
copyBtn.className = 'copy-btn';
copyBtn.textContent = '格式复制';
copyBtn.title = '点击复制格式化后的代码';
// 创建下载按钮
const downloadBtn = document.createElement('button');
downloadBtn.className = 'download-btn';
downloadBtn.textContent = '下载.lsp';
downloadBtn.title = '点击下载为.lsp文件';
// 添加点击事件
copyBtn.addEventListener('click', () => handleCopy(element, copyBtn));
downloadBtn.addEventListener('click', () => handleDownload(element, downloadBtn));
// 插入按钮
buttonsContainer.appendChild(copyBtn);
buttonsContainer.appendChild(downloadBtn);
titleElement.appendChild(buttonsContainer);
});
}
// 初始化函数
function init() {
addStyles();
addCodeButtons();
// 监听DOM变化,动态添加按钮
const observer = new MutationObserver(() => {
addCodeButtons();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// 页面加载完成后再次检查
window.addEventListener('load', addCodeButtons);
}
// 延迟初始化,确保页面加载完成
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
这个更加高级了 这个更好 点击格式复制,直接复制到篡改猴里面会有一处格式有问题的地方,不知道什么原因,如果直接从下到上手选复制就没有这个问题了
http://www.mjtd.com/static/image/common/emp.gif
感谢,好用
更高级了 可以下载为lsp了 这个更加高级了 这个可以,很实用 本帖最后由 szhorse 于 2025-12-11 11:32 编辑
这个太给力了
感谢大佬脚本,确实方便了不少,部分代码【下载.lsp】后,运行时提示缺括号,跑不起来
测试了这个http://bbs.mjtd.com/thread-193886-1-1.html,会缺括号
页:
[1]
2