User:Kurgenera/killRSP.js
外观
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
//这玩意误杀率至少有15%,但编者有复核的机会。误杀结果与脚本制作者无关,仅与执行者相关。
//已知bug:[[Special:Diff/91937521]]
$(function() {
'use strict';
// ================= 配置区 =================
const PORTAL_DOMAINS = ['sina', 'sohu', '163', 'ifeng', 'qq', 'weibo', 'baidu','huxiu', 'msn', 'armyrecognition'];
const SOCIAL_DOMAINS = ['youtube', 'facebook', 'x.com', 'twitter', 'instagram'];
const KEYWORDS = ['新浪', '搜狐', '网易', '凤凰', '腾讯'];
const EXEMPT_DOMAINS = ['\\.gov\\.cn', '\\.edu\\.cn', 'rfa\\.org'];
// ==========================================
var modalCSS =
'#maint-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.7); z-index: 99999; }' +
'#maint-modal { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #fff; padding: 25px; border: 1px solid #ccc; border-radius: 5px; z-index: 100000; width: 650px; max-width: 95%; box-shadow: 0 0 20px rgba(0,0,0,0.5); font-family: sans-serif; }' +
'#maint-modal h2 { margin-top: 0; border-bottom: 2px solid #d33; padding-bottom: 10px; color: #d33; font-size: 1.1em; }' +
'#maint-modal .source-scroll { max-height: 450px; overflow-y: auto; margin: 15px 0; border: 1px solid #eee; padding: 10px; background: #f9f9f9; }' +
'#maint-modal .source-item { display: block; margin-bottom: 15px; border-bottom: 2px solid #eee; padding-bottom: 10px; }' +
'#maint-modal .source-content { font-size: 12px; color: #444; background: #fff; border-left: 3px solid #d33; padding: 5px 8px; margin: 5px 0; word-break: break-all; }' +
'#maint-modal .badge-danger { background: #f8d7da; color: #721c24; font-size: 10px; padding: 2px 5px; border-radius: 3px; font-weight: bold; margin-right: 8px; border: 1px solid #f5c6cb; }' +
'#maint-modal .badge-warn { background: #fff3cd; color: #856404; font-size: 10px; padding: 2px 5px; border-radius: 3px; font-weight: bold; margin-right: 8px; border: 1px solid #ffeeba; }' +
'#maint-modal .source-link { color: #3366cc; text-decoration: none; font-size: 11px; font-family: monospace; }' +
'#maint-modal .source-link:hover { text-decoration: underline; }' +
'#maint-modal button { padding: 12px; background-color: #d33; color: white; border: none; border-radius: 3px; cursor: pointer; font-weight: bold; width: 100%; font-size: 1.1em; }' +
'.maint-close { float: right; cursor: pointer; font-size: 1.5em; color: #aaa; line-height: 0.8; }';
mw.util.addCSS(modalCSS);
var portletLink = mw.util.addPortletLink('p-cactions', '#', 'KILLRSP', 'ca-killrsp-v14', '斩杀工具:带源码预览的高级版');
$(portletLink).on('click', function(e) {
e.preventDefault();
if ($('#maint-overlay').length) return;
var api = new mw.Api();
var pageTitle = mw.config.get('wgPageName');
mw.notify('正在深度解析引用内容...', { autoHide: true });
api.get({
action: 'query',
prop: 'revisions',
titles: pageTitle,
rvprop: 'content',
rvlimit: 1,
formatversion: 2
}).done(function(data) {
var page = data.query.pages[0];
if (page.missing) return;
var wikitext = page.revisions[0].content;
var allRefs = wikitext.match(/<ref[^>]*>[\s\S]*?(?:\/>|<\/ref>)/gi);
if (!allRefs) {
mw.notify('未发现引用。');
return;
}
var targets = PORTAL_DOMAINS.concat(SOCIAL_DOMAINS).concat(KEYWORDS);
var checkRe = new RegExp(targets.join('|'), 'i');
var exemptRe = new RegExp(EXEMPT_DOMAINS.join('|'), 'i');
var matches = allRefs.filter(function(ref) {
// 确保排除空引用和豁免项
return checkRe.test(ref) && !exemptRe.test(ref) && ref.length > 10;
});
if (matches.length === 0) {
mw.notify('干净如新,无需斩杀。');
return;
}
renderKillPanel(wikitext, Array.from(new Set(matches)), api, pageTitle);
});
function renderKillPanel(originalText, sources, api, title) {
var $overlay = $('<div id="maint-overlay">').appendTo('body');
var $modal = $('<div>').attr('id', 'maint-modal').appendTo('body');
$modal.html('<span class="maint-close">×</span><h2>KILLRSP: 斩杀决策终端</h2>');
var $scroll = $('<div class="source-scroll">');
var portalRe = new RegExp('(' + PORTAL_DOMAINS.join('|') + ')', 'i');
sources.forEach(function(src) {
var isPortal = portalRe.test(src);
var $item = $('<div>').addClass('source-item');
// 提取预览用的文字内容:去除标签,保留核心参数
var previewText = src.replace(/<[^>]+>/g, '').replace(/[\r\n\t]+/g, ' ').trim();
if (previewText.length > 120) previewText = previewText.substring(0, 120) + '...';
if (!previewText) previewText = "(自闭合或无文本引用: " + src.match(/name\s*=\s*["']?([^"'>\s/]+)/i)[1] + ")";
var $checkbox = $('<input type="checkbox" name="u-src">').val(src);
var $header = $('<div style="margin-bottom:5px;">').append($checkbox);
if (isPortal) {
$header.append($('<span>').addClass('badge-danger').text('高度确信'));
$checkbox.prop('checked', true);
} else {
$header.append($('<span>').addClass('badge-warn').text('疑似 URG'));
}
$item.append($header);
$item.append($('<div>').addClass('source-content').text(previewText));
var urlMatch = src.match(/\|?\s*url\s*=\s*(https?:\/\/[^\s|}\[\]]+)/i) || src.match(/https?:\/\/[^\s|}<>\]]+/);
if (urlMatch) {
var safeUrl = (urlMatch[1] || urlMatch[0]).replace(/^http:/i, 'https:');
$item.append($('<a>').attr({
href: safeUrl,
target: '_blank',
class: 'source-link'
}).text('🌐 预览链接: ' + safeUrl));
}
$scroll.append($item);
});
var $btn = $('<button>天生万物以养人,人无一物以报天,杀杀杀杀杀杀杀!</button>').on('click', function() {
var selected = [];
$('input[name="u-src"]:checked').each(function() { selected.push($(this).val()); });
if (!selected.length) return;
var newText = originalText;
selected.forEach(function(item) {
var escapedItem = item.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
newText = newText.replace(new RegExp(escapedItem, 'g'), '');
// 同时尝试清理基于 name 的复用标签
var nameMatch = item.match(/<ref[^>]+name\s*=\s*["']?([^"'>\s/]+)["']?[^>]*>/i);
if (nameMatch) {
var refName = nameMatch[1].replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
newText = newText.replace(new RegExp('<ref\\s+name\\s*=\\s*["\']?' + refName + '["\']?\\s*\\/>', 'gi'), '');
}
});
api.postWithToken('csrf', {
action: 'edit',
title: title,
text: newText,
summary: '批量移除不可靠来源 (使用[[User:Kurgenera/killRSP.js]])',
nocreate: true
}).done(function() {
mw.notify('斩杀任务已执行。');
setTimeout(function() { location.reload(); }, 1000);
});
$overlay.add($modal).remove();
});
$modal.append($scroll, $btn);
$overlay.add('.maint-close').on('click', function() { $overlay.add($modal).remove(); });
}
});
});