User:人间百态/AbuseFilterContribs.js
外观
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
//copy from [[:en:User:Ingenuity/AbuseFilterContribs.js]]
(function() {
const afcAPI = new mw.Api();
if (mw.config.get("wgCanonicalSpecialPageName") === "Contributions" && mw.config.values.wgRelevantUserName) {
addToContribs(mw.config.values.wgRelevantUserName);
}
async function loadAbuseFilterLog(user) {
return (await afcAPI.get({
action: "query",
list: "abuselog",
afllimit: 50,
afluser: user
})).query.abuselog.filter(e => e.result === "disallow").sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));
}
function groupAbuseLog(log) {
const data = [];
outer: for (const item of log) {
for (const i of data) {
if (i.timestamp === item.timestamp && i.title === item.title) {
i.filters.push(item.filter_id);
if (item.filter_id) {
i.id = item.id;
}
continue outer;
}
}
data.push({
timestamp: item.timestamp,
filters: [item.filter_id],
id: item.id,
title: item.title
});
}
return data;
}
async function addToContribs(user) {
const log = groupAbuseLog(await loadAbuseFilterLog(user));
const cList = document.querySelectorAll(".mw-contributions-list");
const children = [];
for (const item of cList) {
children.push(...item.children);
}
const settings = await getSettings();
const offset = getOffset(settings);
const times = await getTimes(children.map(e => e.attributes["data-mw-revid"].value));
hits: for (const hit of log) {
for (let i = children.length - 1; i > -1; i--) {
const child = children[i];
const id = Array.prototype.slice.call(child.attributes).filter(a => a.nodeName === "data-mw-revid")[0].value;
const ts = times.filter(e => e.id === Number(id))[0].timestamp;
if (new Date(hit.timestamp) < new Date(ts)) {
const elem = document.createElement("li");
elem.style.background = "rgba(255, 0, 0, 0.13)";
elem.style.borderRadius = "3px";
child.parentElement.insertBefore(elem, child.nextSibling);
elem.innerHTML = createText(hit, offset, settings);
continue hits;
}
}
const noContribsElem = document.querySelector("#mw-content-text > p");
if (!noContribsElem) {
const contribsList = document.querySelector(".mw-contributions-list");
const elem = document.createElement("li");
elem.style.background = "rgba(255, 0, 0, 0.13)";
elem.style.borderRadius = "3px";
contribsList.insertBefore(elem, contribsList.children[0]);
elem.innerHTML = createText(hit, offset, settings);
} else {
noContribsElem.remove();
const ul = document.createElement("ul");
ul.innerHTML = `<ul class="mw-contributions-list"><li style="background: rgba(255, 0, 0, 0.13); border-radius: 3px;">${createText(hit, offset, settings)}</li></ul>`;
document.querySelector("#mw-content-text").insertBefore(ul, document.querySelector(".mw-contributions-footer"));
}
}
}
function createText(hit, offset, settings) {
const adj = new Date(new Date(hit.timestamp).getTime() + offset * 60 * 1000);
const details = hit.filters.filter(e => e).length ? `(<a href="/wiki/Special:滥用日志/${hit.id}">详情</a> | <a href="/wiki/Special:滥用过滤器/examine/log/${hit.id}">检查</a>)` : "";
return `
${getTimestampString(settings, adj.getUTCFullYear(), adj.getUTCMonth(), adj.getUTCDate(), adj.getUTCHours(), adj.getUTCMinutes(), adj.getUTCSeconds())}:
在<a href="/wiki/${encodeURIComponent(hit.title)}">${hit.title}</a>触发了${getLogText(hit.filters)}
${details}
`;
}
function getLogText(filters) {
if (filters.length === 1) {
return filters[0] ? `<a href="/wiki/Special:滥用过滤器/${filters[0]}">filter ${filters[0]}</a>` : "a private edit filter";
}
return `${filters.length} filters (${filters.map(e => {
return e ? `<a href="/wiki/Special:滥用过滤器/${e}">${e}</a>` : "private";
}).join(", ")})`;
}
async function getTimes(ids) {
if (ids.length === 0) {
return [];
}
const data = [];
Object.values((await afcAPI.get({
action: "query",
revids: ids.join("|"),
prop: "revisions",
rvprop: "timestamp|ids"
})).query.pages).forEach(e => {
for (const r of e.revisions) {
data.push({
id: r.revid,
timestamp: r.timestamp
});
}
});
return data.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
}
async function getSettings() {
return (await afcAPI.get({
action: "query",
meta: "userinfo",
uiprop: "options"
})).query.userinfo.options;
}
function getOffset(settings) {
const match = settings.timecorrection.match(/([+-]?\d+)/);
return match ? Number(match[1]) : 0;
}
function getTimestampString(settings, year, month, day, hour, minute, second) {
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
switch (settings.date) {
case "dmy":
case "default":
return `${pad(hour)}:${pad(minute)}, ${day} ${monthNames[month]} ${year}`;
case "mdy":
return `${pad(hour)}:${pad(minute)}, ${monthNames[month]} ${day}, ${year}`;
case "ymd":
return `${pad(hour)}:${pad(minute)}, ${year} ${monthNames[month]} ${day}`;
default:
return `${year}-${pad(month + 1)}-${pad(day)}T${pad(hour)}:${pad(minute)}:${pad(second)}`;
}
}
function pad(num) {
return num < 10 ? "0" + num : num;
}
})();