MediaWiki:Gadget-ShowContributors.js:修订间差异
MediaWiki界面页面
更多操作
![]() OctoberSama(留言 | 贡献) 小 |
![]() OctoberSama(留言 | 贡献) 小 |
||
第1行: | 第1行: | ||
(() => { | (() => { | ||
"use strict"; | "use strict"; | ||
$(() => (async () => { | $((() => (async () => { | ||
if ( | if ( | ||
![0, 2, 4, 10, 12, 14, 828, 274].includes(mw.config.get("wgNamespaceNumber")) || | ![0, 2, 4, 10, 12, 14, 828, 274].includes(mw.config.get("wgNamespaceNumber")) || | ||
mw.config.get("wgArticleId") | 0 === mw.config.get("wgArticleId") || | ||
!["view", "history"].includes(mw.config.get("wgAction")) | !["view", "history"].includes(mw.config.get("wgAction")) | ||
) return; | ) | ||
return; | |||
mw.loader.addStyleTag(` | mw.loader.addStyleTag(` | ||
#show-contributor-button { | #show-contributor-button { | ||
float: right; | |||
margin-left: .5em; | |||
margin-right: 0 | |||
} | } | ||
#show-contributor-header { | #show-contributor-header { | ||
background: #fff; | |||
border-bottom: 1px solid #aaa; | |||
font-weight: 600; | |||
padding: .3em; | |||
position: sticky; | |||
text-align: center; | |||
top: 0 | |||
} | |||
} | #show-contributor-headline { | ||
#show-contributor-headline { | font-size: 1.3em | ||
} | |||
} | #show-contributor-close { | ||
#show-contributor-close { | border-radius: 50%; | ||
cursor: pointer; | |||
position: absolute; | |||
right: 5px; | |||
top: 5px | |||
} | |||
} | #show-contributor-close:hover { | ||
#show-contributor-close:hover { | background-color: #eee | ||
} | |||
} | #show-contributor-table { | ||
#show-contributor-table { | margin: 0; | ||
width: 100% | |||
} | |||
} | #show-contributor-table .user-avatar { | ||
#show-contributor-table .user-avatar { | border-radius: 50%; | ||
height: 20px; | |||
width: 20px | |||
} | |||
} | /* Citizen 皮肤响应式样式 */ | ||
.skin-citizen #show-contributor-button { | .skin-citizen #show-contributor-button { | ||
float: none; | |||
margin: 0 0.5em 0 0; | |||
} | display: inline-flex; | ||
@media ( | align-items: center; | ||
vertical-align: middle; | |||
} | |||
@media (min-width: 1120px) { | |||
.skin-citizen .citizen-page-header-inner { | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
} | |||
} | .skin-citizen .citizen-page-heading { | ||
`); | flex-grow: 1; | ||
} | |||
} | |||
@media (max-width: 1119px) { | |||
.skin-citizen #show-contributor-button { | |||
margin: 0.5em 0; | |||
display: block; | |||
} | |||
} | |||
`); | |||
await mw.loader.using([ | await mw.loader.using(["mediawiki.api","mediawiki.notification","oojs-ui","oojs-ui.styles.icons-interactions","jquery.tablesorter"]); | ||
class | class t extends OO.ui.Dialog { | ||
$table = $('<table id="show-contributor-table" class="wikitable" />'); | $table = $('<table id="show-contributor-table" class="wikitable" />'); | ||
$tbody = $("<tbody />"); | $tbody = $("<tbody />"); | ||
got = | $body; | ||
got = !1; | |||
static static = { | static static = {...super.static,name:"ShowContributor",tagName:"div"}; | ||
initialize() { | initialize() { | ||
super.initialize() | return super.initialize(), | ||
this.$body.append( | this.$body.append( | ||
$('<div id="show-contributor-header" />').append( | $('<div id="show-contributor-header" />').append( | ||
$('<div id="show-contributor-headline">本页贡献统计</div>'), | $('<div id="show-contributor-headline">本页贡献统计</div>'), | ||
new OO.ui.IconWidget({ | new OO.ui.IconWidget({icon:"close",id:"show-contributor-close"}).$element.on("click",(()=>this.close())) | ||
), | ), | ||
this.$table.append( | this.$table.append( | ||
第95行: | 第91行: | ||
this.$tbody | this.$tbody | ||
) | ) | ||
) | ), | ||
this | |||
} | } | ||
getContributors = async () => { | |||
async | const t = new mw.Api, | ||
const | e = {}; | ||
let o = "", | |||
let | i = 0; | ||
const r = { | |||
action:"query", | |||
const | format:"json", | ||
action: "query", | prop:"revisions", | ||
format: "json", | titles:mw.config.get("wgPageName"), | ||
prop: "revisions", | rvprop:"user|size", | ||
titles: mw.config.get("wgPageName"), | rvlimit:"max", | ||
rvprop: "user|size", | rvdir:"newer" | ||
rvlimit: "max", | |||
rvdir: "newer" | |||
}; | }; | ||
do { | do { | ||
o && (r.rvcontinue = o); | |||
try { | try { | ||
const | const n = await t.get(r); | ||
o = n.continue?.rvcontinue; | |||
for (const { user, size } of Object.values( | for (const {user:t,size:o} of Object.values(n.query.pages)[0].revisions) | ||
e[t] ||= [], | |||
e[t].push(o - i), | |||
i = o | |||
} catch (t) { | |||
} catch ( | mw.notify(`获取编辑记录失败:${t}`,{type:"error"}) | ||
mw.notify(`获取编辑记录失败:${ | |||
} | } | ||
} while ( | } while (o); | ||
return e | |||
return | }; | ||
} | addRow = (t,{user:e,count:o,add:i,remove:r}) => { | ||
t.append( | |||
addRow( | |||
$("<tr />").append( | $("<tr />").append( | ||
$("<td />").append( | $("<td />").append( | ||
$(`<a href="${mw.config.get("wgArticlePath").replace("$1", `User:${ | $(`<a href="${mw.config.get("wgArticlePath").replace("$1",`User:${e}`)}" />`).append( | ||
`<img class="user-avatar" src="https://commons.moegirl.org.cn/extensions/Avatar/avatar.php?user=${ | `<img class="user-avatar" src="https://commons.moegirl.org.cn/extensions/Avatar/avatar.php?user=${e}" />`, | ||
e | |||
) | ) | ||
), | ), | ||
`<td>${ | `<td>${o}</td>`, | ||
`<td>${ | `<td>${i}</td>`, | ||
`<td>${ | `<td>${r}</td>` | ||
) | ) | ||
) | ) | ||
} | }; | ||
showContributors = t => { | |||
showContributors | |||
this.$tbody.empty(); | this.$tbody.empty(); | ||
for (const | for (const e in t) | ||
this.addRow(this.$tbody,{ | |||
this.addRow(this.$tbody, { | user:e, | ||
user, | count:t[e].length, | ||
count: | add:t[e].reduce(((t,e)=>e>0?t+e:t),0), | ||
add: | remove:t[e].reduce(((t,e)=>e<0?t+e:t),0) | ||
remove: | |||
}); | }); | ||
this.got = !0 | |||
this.got = | |||
} | } | ||
} | } | ||
// 确保这些变量在点击事件处理函数中可访问 | |||
const | const e = new OO.ui.WindowManager({id:"show-contributor"}); | ||
$(document.body).append( | $(document.body).append(e.$element); | ||
const o = new t({size:"large"}); // 这是对话框实例 | |||
e.addWindows([o]); | |||
const | const i = new OO.ui.ButtonWidget({ | ||
label: "本页贡献者", | label:"本页贡献者", | ||
icon: "search", | icon:"search", | ||
flags: "progressive", | flags:"progressive", | ||
id: "show-contributor-button" | id:"show-contributor-button" | ||
}) | }); | ||
// 响应式插入逻辑 | |||
if ("citizen" === mw.config.get("skin")) { | |||
$ | const handleResize = () => { | ||
$("#show-contributor-button").detach(); | |||
if (window.matchMedia("(min-width: 1120px)").matches) { | |||
$(".page-actions").prepend(i.$element); | |||
$ | } else { | ||
} | $(".citizen-page-heading").append(i.$element); | ||
} | |||
}; | |||
handleResize(); | |||
$(window).on("resize", handleResize); | |||
} else { | |||
$("#bodyContent").prepend(i.$element); | |||
} | |||
$("# | |||
// 点击事件处理(确保能访问到 o 和 e) | |||
i.on("click", async () => { | |||
if (!o.got) { | |||
i.setLabel("正在查询"); | |||
const t = await o.getContributors(); | |||
o.showContributors(t), | |||
o.$table.tablesorter(), | |||
i.setLabel("本页贡献者") | |||
} | } | ||
e.openWindow(o); | |||
}); | }); | ||
})())) | |||
})()) | |||
})(); | })(); |
2025年6月11日 (三) 12:04的版本
(() => { "use strict"; $((() => (async () => { if ( ![0, 2, 4, 10, 12, 14, 828, 274].includes(mw.config.get("wgNamespaceNumber")) || 0 === mw.config.get("wgArticleId") || !["view", "history"].includes(mw.config.get("wgAction")) ) return; mw.loader.addStyleTag(` #show-contributor-button { float: right; margin-left: .5em; margin-right: 0 } #show-contributor-header { background: #fff; border-bottom: 1px solid #aaa; font-weight: 600; padding: .3em; position: sticky; text-align: center; top: 0 } #show-contributor-headline { font-size: 1.3em } #show-contributor-close { border-radius: 50%; cursor: pointer; position: absolute; right: 5px; top: 5px } #show-contributor-close:hover { background-color: #eee } #show-contributor-table { margin: 0; width: 100% } #show-contributor-table .user-avatar { border-radius: 50%; height: 20px; width: 20px } /* Citizen 皮肤响应式样式 */ .skin-citizen #show-contributor-button { float: none; margin: 0 0.5em 0 0; display: inline-flex; align-items: center; vertical-align: middle; } @media (min-width: 1120px) { .skin-citizen .citizen-page-header-inner { display: flex; justify-content: space-between; align-items: center; } .skin-citizen .citizen-page-heading { flex-grow: 1; } } @media (max-width: 1119px) { .skin-citizen #show-contributor-button { margin: 0.5em 0; display: block; } } `); await mw.loader.using(["mediawiki.api","mediawiki.notification","oojs-ui","oojs-ui.styles.icons-interactions","jquery.tablesorter"]); class t extends OO.ui.Dialog { $table = $('<table id="show-contributor-table" class="wikitable" />'); $tbody = $("<tbody />"); $body; got = !1; static static = {...super.static,name:"ShowContributor",tagName:"div"}; initialize() { return super.initialize(), this.$body.append( $('<div id="show-contributor-header" />').append( $('<div id="show-contributor-headline">本页贡献统计</div>'), new OO.ui.IconWidget({icon:"close",id:"show-contributor-close"}).$element.on("click",(()=>this.close())) ), this.$table.append( $("<thead><th>用户</th><th>编辑数</th><th>增加字节数</th><th>删减字节数</th></thead>"), this.$tbody ) ), this } getContributors = async () => { const t = new mw.Api, e = {}; let o = "", i = 0; const r = { action:"query", format:"json", prop:"revisions", titles:mw.config.get("wgPageName"), rvprop:"user|size", rvlimit:"max", rvdir:"newer" }; do { o && (r.rvcontinue = o); try { const n = await t.get(r); o = n.continue?.rvcontinue; for (const {user:t,size:o} of Object.values(n.query.pages)[0].revisions) e[t] ||= [], e[t].push(o - i), i = o } catch (t) { mw.notify(`获取编辑记录失败:${t}`,{type:"error"}) } } while (o); return e }; addRow = (t,{user:e,count:o,add:i,remove:r}) => { t.append( $("<tr />").append( $("<td />").append( $(`<a href="${mw.config.get("wgArticlePath").replace("$1",`User:${e}`)}" />`).append( `<img class="user-avatar" src="https://commons.moegirl.org.cn/extensions/Avatar/avatar.php?user=${e}" />`, e ) ), `<td>${o}</td>`, `<td>${i}</td>`, `<td>${r}</td>` ) ) }; showContributors = t => { this.$tbody.empty(); for (const e in t) this.addRow(this.$tbody,{ user:e, count:t[e].length, add:t[e].reduce(((t,e)=>e>0?t+e:t),0), remove:t[e].reduce(((t,e)=>e<0?t+e:t),0) }); this.got = !0 } } // 确保这些变量在点击事件处理函数中可访问 const e = new OO.ui.WindowManager({id:"show-contributor"}); $(document.body).append(e.$element); const o = new t({size:"large"}); // 这是对话框实例 e.addWindows([o]); const i = new OO.ui.ButtonWidget({ label:"本页贡献者", icon:"search", flags:"progressive", id:"show-contributor-button" }); // 响应式插入逻辑 if ("citizen" === mw.config.get("skin")) { const handleResize = () => { $("#show-contributor-button").detach(); if (window.matchMedia("(min-width: 1120px)").matches) { $(".page-actions").prepend(i.$element); } else { $(".citizen-page-heading").append(i.$element); } }; handleResize(); $(window).on("resize", handleResize); } else { $("#bodyContent").prepend(i.$element); } // 点击事件处理(确保能访问到 o 和 e) i.on("click", async () => { if (!o.got) { i.setLabel("正在查询"); const t = await o.getContributors(); o.showContributors(t), o.$table.tablesorter(), i.setLabel("本页贡献者") } e.openWindow(o); }); })())) })();