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

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

MediaWiki界面页面
第1行: 第1行:
(() => {
(function () {
     "use strict";
     "use strict";
     $((() => (async () => {
 
        if (
     function insertStyles() {
            ![0, 2, 4, 10, 12, 14, 828, 274].includes(mw.config.get("wgNamespaceNumber")) ||
         mw.loader.addStyleTag([
            0 === mw.config.get("wgArticleId") ||
             "#show-contributor-button { float: right; margin-left: .5em; margin-right: 0; }",
            !["view", "history"].includes(mw.config.get("wgAction"))
             "#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; }",
            return;
             "#show-contributor-close { border-radius: 50%; cursor: pointer; position: absolute; right: 5px; top: 5px; }",
       
             "#show-contributor-close:hover { background-color: #eee; }",
         mw.loader.addStyleTag(`
             "#show-contributor-table { margin: 0; width: 100%; }",
             #show-contributor-button {
             "#show-contributor-table .user-avatar { border-radius: 50%; height: 20px; width: 20px; }",
                float: right;
             ".skin-citizen #show-contributor-button { float: none; margin: 0 0.5em 0 0; display: inline-flex; align-items: center; vertical-align: middle; }",
                margin-left: .5em;
             "@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; } }",
                margin-right: 0;
            "@media (max-width: 1119px) { .skin-citizen #show-contributor-button { margin: 0.5em 0; display: block; } }"
            }
        ].join("\n"));
             #show-contributor-header {
    }
                background: #fff;
 
                border-bottom: 1px solid #aaa;
    function isValidPage() {
                font-weight: 600;
        var ns = mw.config.get("wgNamespaceNumber");
                padding: .3em;
        var action = mw.config.get("wgAction");
                position: sticky;
        return [0, 2, 4, 10, 12, 14, 828, 274].indexOf(ns) !== -1 &&
                text-align: center;
            mw.config.get("wgArticleId") !== 0 &&
                top: 0;
            (action === "view" || action === "history");
            }
    }
             #show-contributor-headline {
 
                font-size: 1.3em;
    function ShowContributorDialog(config) {
            }
        ShowContributorDialog.super.call(this, config);
             #show-contributor-close {
    }
                border-radius: 50%;
 
                cursor: pointer;
    OO.inheritClass(ShowContributorDialog, OO.ui.Dialog);
                position: absolute;
 
                right: 5px;
    ShowContributorDialog.static.name = "ShowContributor";
                top: 5px;
    ShowContributorDialog.static.tagName = "div";
            }
 
             #show-contributor-close:hover {
    ShowContributorDialog.prototype.initialize = function () {
                background-color: #eee;
        ShowContributorDialog.super.prototype.initialize.call(this);
            }
        this.got = false;
             #show-contributor-table {
        this.$table = $('<table id="show-contributor-table" class="wikitable" />');
                margin: 0;
        this.$tbody = $("<tbody />");
                width: 100%;
        this.$body.append(
            }
            $('<div id="show-contributor-header" />').append(
             #show-contributor-table .user-avatar {
                $('<div id="show-contributor-headline">本页贡献统计</div>'),
                border-radius: 50%;
                new OO.ui.IconWidget({ icon: "close", id: "show-contributor-close" }).$element.on("click", this.close.bind(this))
                height: 20px;
            ),
                width: 20px;
            this.$table.append(
            }
                $("<thead><th>用户</th><th>编辑数</th><th>增加字节数</th><th>删减字节数</th></thead>"),
             .skin-citizen #show-contributor-button {
                this.$tbody
                float: none;
            )
                margin: 0 0.5em 0 0;
        );
                display: inline-flex;
    };
                align-items: center;
 
                vertical-align: middle;
    ShowContributorDialog.prototype.getContributors = function () {
            }
        var self = this;
             @media (min-width: 1120px) {
        var api = new mw.Api();
                .skin-citizen .citizen-page-header-inner {
        var users = {};
                    display: flex;
        var rvcontinue = "";
                    justify-content: space-between;
        var lastSize = 0;
                    align-items: center;
        var params = {
                }
            action: "query",
                .skin-citizen .citizen-page-heading {
            format: "json",
                    flex-grow: 1;
            prop: "revisions",
            titles: mw.config.get("wgPageName"),
            rvprop: "user|size",
            rvlimit: "max",
            rvdir: "newer"
        };
 
        function handleResponse(data) {
            if (data.continue) rvcontinue = data.continue.rvcontinue;
            else rvcontinue = null;
            var revisions = Object.values(data.query.pages)[0].revisions;
            revisions.forEach(function (rev) {
                if (!users[rev.user]) users[rev.user] = [];
                users[rev.user].push(rev.size - lastSize);
                lastSize = rev.size;
            });
        }
 
        return new Promise(function (resolve) {
            function next() {
                if (rvcontinue !== null) {
                    if (rvcontinue) params.rvcontinue = rvcontinue;
                    api.get(params).done(function (data) {
                        handleResponse(data);
                        next();
                    }).fail(function (err) {
                        mw.notify("获取编辑记录失败:" + err, { type: "error" });
                        rvcontinue = null;
                        resolve(users);
                    });
                } else {
                    resolve(users);
                 }
                 }
             }
             }
             @media (max-width: 1119px) {
             next();
                .skin-citizen #show-contributor-button {
        });
                    margin: 0.5em 0;
    };
                    display: block;
 
                }
    ShowContributorDialog.prototype.addRow = function ($tbody, data) {
            }
        var $row = $("<tr />").append(
         `);
            $("<td />").append(
                $('<a href="' + mw.config.get("wgArticlePath").replace("$1", "User:" + data.user) + '" />').text(data.user)
            ),
            $("<td />").text(data.count),
            $("<td />").text(data.add),
            $("<td />").text(data.remove)
        );
        $tbody.append($row);
    };
 
    ShowContributorDialog.prototype.showContributors = function (users) {
        var self = this;
        this.$tbody.empty();
        Object.keys(users).forEach(function (user) {
            var edits = users[user];
            var add = edits.reduce(function (sum, n) { return n > 0 ? sum + n : sum; }, 0);
            var remove = edits.reduce(function (sum, n) { return n < 0 ? sum + n : sum; }, 0);
            self.addRow(self.$tbody, {
                user: user,
                count: edits.length,
                add: add,
                remove: remove
            });
        });
        this.got = true;
    };
 
    function main() {
         if (!isValidPage()) return;
        insertStyles();


         await mw.loader.using([
         mw.loader.using([
             "mediawiki.api",
             "mediawiki.api",
             "mediawiki.notification",
             "mediawiki.notification",
第77行: 第137行:
             "oojs-ui.styles.icons-interactions",
             "oojs-ui.styles.icons-interactions",
             "jquery.tablesorter"
             "jquery.tablesorter"
         ]);
         ], function () {
            var winManager = new OO.ui.WindowManager({ id: "show-contributor" });
            $(document.body).append(winManager.$element);
            var dialog = new ShowContributorDialog({ size: "large" });
            winManager.addWindows([dialog]);
 
            var button = new OO.ui.ButtonWidget({
                label: "本页贡献者",
                icon: "search",
                flags: "progressive",
                id: "show-contributor-button"
            });


        class t extends OO.ui.Dialog {
             var insertButton = function () {
            $table = $('<table id="show-contributor-table" class="wikitable" />');
                 $("#show-contributor-button").detach();
            $tbody = $("<tbody />");
                var skin = mw.config.get("skin");
            $body;
                 if (skin === "citizen") {
             got = !1;
                     if (window.innerWidth >= 1120) {
            static static = {...super.static,name:"ShowContributor",tagName:"div"};
                         $(".page-actions").prepend(button.$element);
            initialize() {
                     } else {
                 return super.initialize(),
                         $(".firstHeading-container").append(button.$element);
                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);
                 } else if (skin === "vector-2022") {
                return e
                     $("header.mw-body-header.vector-page-titlebar").append(button.$element);
            };
                } else {
            addRow = (t,{user:e,count:o,add:i,remove:r}) => {
                    $("#bodyContent").prepend(button.$element);
                t.append(
                 }
                     $("<tr />").append(
                        $("<td />").append(
                            $(`<a href="${mw.config.get("wgArticlePath").replace("$1",`User:${e}`)}" />`).text(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((s,n)=>n>0?s+n:s,0),
                        remove:t[e].reduce((s,n)=>n<0?s+n:s,0)
                    });
                this.got = !0
            }
        }


        const e = new OO.ui.WindowManager({id:"show-contributor"});
            insertButton();
        $(document.body).append(e.$element);
        const o = new t({size:"large"});
        e.addWindows([o]);


        const i = new OO.ui.ButtonWidget({
            var isWide = window.innerWidth >= 1120;
            label:"本页贡献者",
            $(window).on("resize", function () {
            icon:"search",
                clearTimeout(window.__showContributorResizeTimer);
            flags:"progressive",
                window.__showContributorResizeTimer = setTimeout(function () {
             id:"show-contributor-button"
                    var nowWide = window.innerWidth >= 1120;
        });
                    if (nowWide !== isWide) {
                        isWide = nowWide;
                        insertButton();
                    }
                }, 200);
             });


        const insertButton = () => {
            button.on("click", function () {
            $("#show-contributor-button").detach();
                if (!dialog.got) {
            const skin = mw.config.get("skin");
                    button.setLabel("正在查询");
            if (skin === "citizen") {
                    dialog.getContributors().then(function (users) {
                if (window.innerWidth >= 1120) {
                        dialog.showContributors(users);
                    $(".page-actions").prepend(i.$element);
                        dialog.$table.tablesorter();
                        button.setLabel("本页贡献者");
                        winManager.openWindow(dialog);
                    });
                 } else {
                 } else {
                     $(".firstHeading-container").append(i.$element);
                     winManager.openWindow(dialog);
                 }
                 }
             } else if (skin === "vector-2022") {
             });
                $("header.mw-body-header.vector-page-titlebar").append(i.$element);
            } else {
                $("#bodyContent").prepend(i.$element);
            }
        };
 
        // 初始插入
        insertButton();
 
        // 仅在断点穿越时更新插入位置
        let isWide = window.innerWidth >= 1120;
        $(window).on("resize", () => {
            clearTimeout(window.__showContributorResizeTimer);
            window.__showContributorResizeTimer = setTimeout(() => {
                const nowWide = window.innerWidth >= 1120;
                if (nowWide !== isWide) {
                    isWide = nowWide;
                    insertButton();
                }
            }, 200);
         });
         });
    }


        // 点击事件
    $(main);
        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月17日 (二) 17:00的版本

(function () {
    "use strict";

    function insertStyles() {
        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; }",
            ".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; } }"
        ].join("\n"));
    }

    function isValidPage() {
        var ns = mw.config.get("wgNamespaceNumber");
        var action = mw.config.get("wgAction");
        return [0, 2, 4, 10, 12, 14, 828, 274].indexOf(ns) !== -1 &&
            mw.config.get("wgArticleId") !== 0 &&
            (action === "view" || action === "history");
    }

    function ShowContributorDialog(config) {
        ShowContributorDialog.super.call(this, config);
    }

    OO.inheritClass(ShowContributorDialog, OO.ui.Dialog);

    ShowContributorDialog.static.name = "ShowContributor";
    ShowContributorDialog.static.tagName = "div";

    ShowContributorDialog.prototype.initialize = function () {
        ShowContributorDialog.super.prototype.initialize.call(this);
        this.got = false;
        this.$table = $('<table id="show-contributor-table" class="wikitable" />');
        this.$tbody = $("<tbody />");
        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.bind(this))
            ),
            this.$table.append(
                $("<thead><th>用户</th><th>编辑数</th><th>增加字节数</th><th>删减字节数</th></thead>"),
                this.$tbody
            )
        );
    };

    ShowContributorDialog.prototype.getContributors = function () {
        var self = this;
        var api = new mw.Api();
        var users = {};
        var rvcontinue = "";
        var lastSize = 0;
        var params = {
            action: "query",
            format: "json",
            prop: "revisions",
            titles: mw.config.get("wgPageName"),
            rvprop: "user|size",
            rvlimit: "max",
            rvdir: "newer"
        };

        function handleResponse(data) {
            if (data.continue) rvcontinue = data.continue.rvcontinue;
            else rvcontinue = null;
            var revisions = Object.values(data.query.pages)[0].revisions;
            revisions.forEach(function (rev) {
                if (!users[rev.user]) users[rev.user] = [];
                users[rev.user].push(rev.size - lastSize);
                lastSize = rev.size;
            });
        }

        return new Promise(function (resolve) {
            function next() {
                if (rvcontinue !== null) {
                    if (rvcontinue) params.rvcontinue = rvcontinue;
                    api.get(params).done(function (data) {
                        handleResponse(data);
                        next();
                    }).fail(function (err) {
                        mw.notify("获取编辑记录失败:" + err, { type: "error" });
                        rvcontinue = null;
                        resolve(users);
                    });
                } else {
                    resolve(users);
                }
            }
            next();
        });
    };

    ShowContributorDialog.prototype.addRow = function ($tbody, data) {
        var $row = $("<tr />").append(
            $("<td />").append(
                $('<a href="' + mw.config.get("wgArticlePath").replace("$1", "User:" + data.user) + '" />').text(data.user)
            ),
            $("<td />").text(data.count),
            $("<td />").text(data.add),
            $("<td />").text(data.remove)
        );
        $tbody.append($row);
    };

    ShowContributorDialog.prototype.showContributors = function (users) {
        var self = this;
        this.$tbody.empty();
        Object.keys(users).forEach(function (user) {
            var edits = users[user];
            var add = edits.reduce(function (sum, n) { return n > 0 ? sum + n : sum; }, 0);
            var remove = edits.reduce(function (sum, n) { return n < 0 ? sum + n : sum; }, 0);
            self.addRow(self.$tbody, {
                user: user,
                count: edits.length,
                add: add,
                remove: remove
            });
        });
        this.got = true;
    };

    function main() {
        if (!isValidPage()) return;
        insertStyles();

        mw.loader.using([
            "mediawiki.api",
            "mediawiki.notification",
            "oojs-ui",
            "oojs-ui.styles.icons-interactions",
            "jquery.tablesorter"
        ], function () {
            var winManager = new OO.ui.WindowManager({ id: "show-contributor" });
            $(document.body).append(winManager.$element);
            var dialog = new ShowContributorDialog({ size: "large" });
            winManager.addWindows([dialog]);

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

            var insertButton = function () {
                $("#show-contributor-button").detach();
                var skin = mw.config.get("skin");
                if (skin === "citizen") {
                    if (window.innerWidth >= 1120) {
                        $(".page-actions").prepend(button.$element);
                    } else {
                        $(".firstHeading-container").append(button.$element);
                    }
                } else if (skin === "vector-2022") {
                    $("header.mw-body-header.vector-page-titlebar").append(button.$element);
                } else {
                    $("#bodyContent").prepend(button.$element);
                }
            };

            insertButton();

            var isWide = window.innerWidth >= 1120;
            $(window).on("resize", function () {
                clearTimeout(window.__showContributorResizeTimer);
                window.__showContributorResizeTimer = setTimeout(function () {
                    var nowWide = window.innerWidth >= 1120;
                    if (nowWide !== isWide) {
                        isWide = nowWide;
                        insertButton();
                    }
                }, 200);
            });

            button.on("click", function () {
                if (!dialog.got) {
                    button.setLabel("正在查询");
                    dialog.getContributors().then(function (users) {
                        dialog.showContributors(users);
                        dialog.$table.tablesorter();
                        button.setLabel("本页贡献者");
                        winManager.openWindow(dialog);
                    });
                } else {
                    winManager.openWindow(dialog);
                }
            });
        });
    }

    $(main);
})();