打开/关闭菜单
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

MediaWiki:Gadget-ShowContributors.js:修订间差异

MediaWiki界面页面
OctoberSama
OctoberSama留言 | 贡献 (dicksuck写坏了)
第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")) ||
             0 === mw.config.get("wgArticleId") ||
             mw.config.get("wgArticleId") === 0 ||
             !["view", "history"].includes(mw.config.get("wgAction"))
             !["view", "history"].includes(mw.config.get("wgAction"))
         )
         ) return;
            return;
 
         mw.loader.addStyleTag(
        // 添加样式
             "#show-contributor-button{float:right;margin-left:.5em;margin-right:0}" +
         mw.loader.addStyleTag(`
             "#show-contributor-header{background:#fff;border-bottom:1px solid #aaa;font-weight:600;padding:.3em;position:sticky;text-align:center;top:0}" +
             #show-contributor-button {
             "#show-contributor-headline{font-size:1.3em}" +
                float: right;
             "#show-contributor-close{border-radius:50%;cursor:pointer;position:absolute;right:5px;top:5px}" +
                margin-left: .5em;
             "#show-contributor-close:hover{background-color:#eee}" +
                margin-right: 0;
             "#show-contributor-table{margin:0;width:100%}" +
            }
             "#show-contributor-table .user-avatar{border-radius:50%;height:20px;width:20px}" +
             #show-contributor-header {
             // 添加 Citizen 皮肤专用样式
                background: #fff;
             ".skin-citizen #show-contributor-button{float:none;margin-left:0;margin-right:.5em;display:inline-flex;align-items:center}" +
                border-bottom: 1px solid #aaa;
             ".skin-citizen .page-actions{display:flex;align-items:center;gap:.5em}"
                font-weight: 600;
         ),
                padding: .3em;
            await mw.loader.using([
                position: sticky;
                "mediawiki.api",
                text-align: center;
                "mediawiki.notification",
                top: 0;
                "oojs-ui",
            }
                "oojs-ui.styles.icons-interactions",
             #show-contributor-headline {
                "jquery.tablesorter"
                font-size: 1.3em;
            ]);
            }
         class t extends OO.ui.Dialog {
             #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 {
                display: inline-flex;
                align-items: center;
            }
            @media screen and (max-width: 1119px) {
                .skin-citizen #show-contributor-button {
                    float: right;
                    margin-left: auto;
                }
            }
             .skin-citizen .page-actions {
                display: flex;
                align-items: center;
                gap: .5em;
            }
         `);
 
        await mw.loader.using([
            "mediawiki.api",
            "mediawiki.notification",
            "oojs-ui",
            "oojs-ui.styles.icons-interactions",
            "jquery.tablesorter"
        ]);
 
         class ContributorDialog extends OO.ui.Dialog {
             $table = $('<table id="show-contributor-table" class="wikitable" />');
             $table = $('<table id="show-contributor-table" class="wikitable" />');
             $tbody = $("<tbody />");
             $tbody = $("<tbody />");
             $body;
             $body;
             got = !1;
             got = false;
             static static = {
             static static = {
                 ...super.static,
                 ...super.static,
第38行: 第83行:
             };
             };
             initialize() {
             initialize() {
                 return super.initialize(),
                 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",
                            icon: "close",
                                id: "show-contributor-close"
                            id: "show-contributor-close"
                            }).$element.on("click", (() => this.close()))
                        }).$element.on("click", () => this.close())
                        ),
                        this.$table.append(
                            $("<thead><th>用户</th><th>编辑数</th><th>增加字节数</th><th>删减字节数</th></thead>"),
                            this.$tbody
                        )
                     ),
                     ),
                     this
                     this.$table.append(
                        $("<thead><tr><th>用户</th><th>编辑数</th><th>增加字节数</th><th>删减字节数</th></tr></thead>"),
                        this.$tbody
                    )
                );
                return this;
             }
             }
             getContributors = async () => {
             getContributors = async () => {
                 const t = new mw.Api,
                 const api = new mw.Api();
                    e = {};
                const users = {};
                 let o = "",
                 let rvcontinue = "";
                    i = 0;
                let lastSize = 0;
                 const r = {
                 const params = {
                     action: "query",
                     action: "query",
                     format: "json",
                     format: "json",
第69行: 第114行:
                 };
                 };
                 do {
                 do {
                     o && (r.rvcontinue = o);
                     if (rvcontinue) params.rvcontinue = rvcontinue;
                     try {
                     try {
                         const n = await t.get(r);
                         const data = await api.get(params);
                         o = n.continue?.rvcontinue;
                         rvcontinue = data.continue?.rvcontinue;
                         for (const {
                         const revisions = Object.values(data.query.pages)[0].revisions;
                            user: t,
                        for (const { user, size } of revisions) {
                            size: o
                             users[user] ||= [];
                        } of Object.values(n.query.pages)[0].revisions)
                            users[user].push(size - lastSize);
                             e[t] ||= [],
                            lastSize = size;
                                e[t].push(o - i),
                        }
                                i = o
                     } catch (err) {
                     } catch (t) {
                         mw.notify(`获取编辑记录失败:${err}`, { type: "error" });
                         mw.notify(`获取编辑记录失败:${t}`, {
                         break;
                            type: "error"
                         })
                     }
                     }
                 } while (o);
                 } while (rvcontinue);
                 return e
                 return users;
             };
             };
             addRow = (t, {
             addRow = (tbody, { user, count, add, remove }) => {
                user: e,
                 tbody.append(
                count: o,
                add: i,
                remove: r
            }) => {
                 t.append(
                     $("<tr />").append(
                     $("<tr />").append(
                         $("<td />").append(
                         $("<td />").append(
                             $(`<a href="${mw.config.get("wgArticlePath").replace("$1", `User:${e}`)}" />`).append(
                             $(`<a href="${mw.config.get("wgArticlePath").replace("$1", `User:${user}`)}" />`).append(
                                 `<img class="user-avatar" src="https://commons.moegirl.org.cn/extensions/Avatar/avatar.php?user=${e}" />`,
                                 `<img class="user-avatar" src="https://commons.moegirl.org.cn/extensions/Avatar/avatar.php?user=${user}" />`,
                                 e
                                 user
                             )
                             )
                         ),
                         ),
                         `<td>${o}</td>`,
                         `<td>${count}</td>`,
                         `<td>${i}</td>`,
                         `<td>${add}</td>`,
                         `<td>${r}</td>`
                         `<td>${remove}</td>`
                     )
                     )
                 )
                 );
             };
             };
             showContributors = t => {
             showContributors = (data) => {
                 this.$tbody.empty();
                 this.$tbody.empty();
                 for (const e in t)
                 for (const user in data) {
                     this.addRow(this.$tbody, {
                     const count = data[user].length;
                        user: e,
                    const add = data[user].reduce((t, v) => v > 0 ? t + v : t, 0);
                        count: t[e].length,
                    const remove = data[user].reduce((t, v) => v < 0 ? t + v : t, 0);
                        add: t[e].reduce(((t, e) => e > 0 ? t + e : t), 0),
                     this.addRow(this.$tbody, { user, count, add, remove });
                        remove: t[e].reduce(((t, e) => e < 0 ? t + e : t), 0)
                }
                     });
                 this.got = true;
                 this.got = !0
             };
             }
         }
         }
         const e = new OO.ui.WindowManager({
 
            id: "show-contributor"
         const windowManager = new OO.ui.WindowManager({ id: "show-contributor" });
        });
         $(document.body).append(windowManager.$element);
         $(document.body).append(e.$element);
 
         const o = new t({
         const dialog = new ContributorDialog({ size: "large" });
            size: "large"
         windowManager.addWindows([dialog]);
        });
 
         e.addWindows([o]);
         const button = new OO.ui.ButtonWidget({
         const i = new OO.ui.ButtonWidget({
             label: "本页贡献者",
             label: "本页贡献者",
             icon: "search",
             icon: "search",
第134行: 第170行:
             id: "show-contributor-button"
             id: "show-contributor-button"
         });
         });
       
 
         // 修改后的插入位置逻辑
         // 插入按钮位置
         if ("citizen" === mw.config.get("skin")) {
         const skin = mw.config.get("skin");
             // 插入到 page-actions 容器中
        const width = window.innerWidth;
             $(".page-actions").prepend(i.$element);
 
        if (skin === "citizen") {
             if (width <= 1119) {
                $(".citizen-page-heading").append(button.$element);
             } else if (width >= 1200) {
                $(".page-actions").prepend(button.$element);
            } else {
                console.warn("宽度不在插入按钮的设定范围内。");
            }
         } else {
         } else {
            // 其他皮肤:保持原逻辑
             $("#bodyContent").prepend(button.$element);
             $("#bodyContent").prepend(i.$element);
         }
         }
       
 
         i.on("click", (async () => {
         button.on("click", async () => {
             if (!o.got) {
             if (!dialog.got) {
                 i.setLabel("正在查询");
                 button.setLabel("正在查询");
                 const t = await o.getContributors();
                 const data = await dialog.getContributors();
                 o.showContributors(t),
                 dialog.showContributors(data);
                    o.$table.tablesorter(),
                dialog.$table.tablesorter();
                    i.setLabel("本页贡献者")
                button.setLabel("本页贡献者");
             }
             }
             e.openWindow(o)
             windowManager.openWindow(dialog);
         }))
         });
     })()))
     })());
})();
})();

2025年6月11日 (三) 00:29的版本

(() => {
    "use strict";
    $(() => (async () => {
        if (
            ![0, 2, 4, 10, 12, 14, 828, 274].includes(mw.config.get("wgNamespaceNumber")) ||
            mw.config.get("wgArticleId") === 0 ||
            !["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 {
                display: inline-flex;
                align-items: center;
            }
            @media screen and (max-width: 1119px) {
                .skin-citizen #show-contributor-button {
                    float: right;
                    margin-left: auto;
                }
            }
            .skin-citizen .page-actions {
                display: flex;
                align-items: center;
                gap: .5em;
            }
        `);

        await mw.loader.using([
            "mediawiki.api",
            "mediawiki.notification",
            "oojs-ui",
            "oojs-ui.styles.icons-interactions",
            "jquery.tablesorter"
        ]);

        class ContributorDialog extends OO.ui.Dialog {
            $table = $('<table id="show-contributor-table" class="wikitable" />');
            $tbody = $("<tbody />");
            $body;
            got = false;
            static static = {
                ...super.static,
                name: "ShowContributor",
                tagName: "div"
            };
            initialize() {
                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><tr><th>用户</th><th>编辑数</th><th>增加字节数</th><th>删减字节数</th></tr></thead>"),
                        this.$tbody
                    )
                );
                return this;
            }
            getContributors = async () => {
                const api = new mw.Api();
                const users = {};
                let rvcontinue = "";
                let lastSize = 0;
                const params = {
                    action: "query",
                    format: "json",
                    prop: "revisions",
                    titles: mw.config.get("wgPageName"),
                    rvprop: "user|size",
                    rvlimit: "max",
                    rvdir: "newer"
                };
                do {
                    if (rvcontinue) params.rvcontinue = rvcontinue;
                    try {
                        const data = await api.get(params);
                        rvcontinue = data.continue?.rvcontinue;
                        const revisions = Object.values(data.query.pages)[0].revisions;
                        for (const { user, size } of revisions) {
                            users[user] ||= [];
                            users[user].push(size - lastSize);
                            lastSize = size;
                        }
                    } catch (err) {
                        mw.notify(`获取编辑记录失败:${err}`, { type: "error" });
                        break;
                    }
                } while (rvcontinue);
                return users;
            };
            addRow = (tbody, { user, count, add, remove }) => {
                tbody.append(
                    $("<tr />").append(
                        $("<td />").append(
                            $(`<a href="${mw.config.get("wgArticlePath").replace("$1", `User:${user}`)}" />`).append(
                                `<img class="user-avatar" src="https://commons.moegirl.org.cn/extensions/Avatar/avatar.php?user=${user}" />`,
                                user
                            )
                        ),
                        `<td>${count}</td>`,
                        `<td>${add}</td>`,
                        `<td>${remove}</td>`
                    )
                );
            };
            showContributors = (data) => {
                this.$tbody.empty();
                for (const user in data) {
                    const count = data[user].length;
                    const add = data[user].reduce((t, v) => v > 0 ? t + v : t, 0);
                    const remove = data[user].reduce((t, v) => v < 0 ? t + v : t, 0);
                    this.addRow(this.$tbody, { user, count, add, remove });
                }
                this.got = true;
            };
        }

        const windowManager = new OO.ui.WindowManager({ id: "show-contributor" });
        $(document.body).append(windowManager.$element);

        const dialog = new ContributorDialog({ size: "large" });
        windowManager.addWindows([dialog]);

        const button = new OO.ui.ButtonWidget({
            label: "本页贡献者",
            icon: "search",
            flags: "progressive",
            id: "show-contributor-button"
        });

        // 插入按钮位置
        const skin = mw.config.get("skin");
        const width = window.innerWidth;

        if (skin === "citizen") {
            if (width <= 1119) {
                $(".citizen-page-heading").append(button.$element);
            } else if (width >= 1200) {
                $(".page-actions").prepend(button.$element);
            } else {
                console.warn("宽度不在插入按钮的设定范围内。");
            }
        } else {
            $("#bodyContent").prepend(button.$element);
        }

        button.on("click", async () => {
            if (!dialog.got) {
                button.setLabel("正在查询");
                const data = await dialog.getContributors();
                dialog.showContributors(data);
                dialog.$table.tablesorter();
                button.setLabel("本页贡献者");
            }
            windowManager.openWindow(dialog);
        });
    })());
})();