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

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

MediaWiki界面页面
(未显示同一用户的30个中间版本)
第1行: 第1行:
(() => {
// 原作者萌娘百科BearBin
//遵循BSD 3-Clause License使用代码
//全文请参见上方文档
//GitHub仓库地址:https://github.com/BearBin1215/MoegirlPedia
(function() {
     "use strict";
     "use strict";
     $(() => (async () => {
     $(function() {
        if (
        (function() {
            ![0, 2, 4, 10, 12, 14, 828, 274].includes(mw.config.get("wgNamespaceNumber")) ||
            if (
            mw.config.get("wgArticleId") === 0 ||
                ![0, 2, 4, 10, 12, 14, 828, 274].includes(mw.config.get("wgNamespaceNumber")) ||
            !["view", "history"].includes(mw.config.get("wgAction"))
                0 === mw.config.get("wgArticleId") ||
        ) return;
                !["view", "history"].includes(mw.config.get("wgAction"))
            )
                return;


        mw.loader.addStyleTag(`
            mw.loader.using([
#show-contributor-button {
                "mediawiki.api",
    float: right;
                "mediawiki.notification",
    margin-left: .5em;
                "oojs-ui",
    margin-right: 0;
                "oojs-ui.styles.icons-interactions",
}
                "jquery.tablesorter"
#show-contributor-header {
            ]).then(function() {
    background: #fff;
                function ShowContributorDialog(config) {
    border-bottom: 1px solid #aaa;
                    OO.ui.Dialog.call(this, config);
    font-weight: 600;
                    this.$table = $('<table id="show-contributor-table" class="wikitable" />');
    padding: .3em;
                    this.$tbody = $("<tbody />");
    position: sticky;
                    this.got = false;
    text-align: center;
                }
    top: 0;
                OO.inheritClass(ShowContributorDialog, OO.ui.Dialog);
    z-index: 1;
                ShowContributorDialog.static = ShowContributorDialog.static || {};
}
                ShowContributorDialog.static.name = "ShowContributor";
#show-contributor-headline {
                ShowContributorDialog.static.tagName = "div";
    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 {
    display: inline-flex;
    align-items: center;
}
@media (max-width: 1119px) {
    #show-contributor-button.citizen-header-button {
        position: absolute;
        right: 0.75em;
        top: 50%;
        transform: translateY(-50%);
        margin: 0;
        z-index: 2;
    }
}
`);


        await mw.loader.using([
                ShowContributorDialog.prototype.initialize = function() {
            "mediawiki.api",
                    OO.ui.Dialog.prototype.initialize.call(this);
            "mediawiki.notification",
                    this.$body.append(
            "oojs-ui",
                        $('<div id="show-contributor-header" />').append(
            "oojs-ui.styles.icons-interactions",
                            $('<div id="show-contributor-headline">本页贡献统计</div>'),
            "jquery.tablesorter"
                            new OO.ui.IconWidget({icon:"close",id:"show-contributor-close"}).$element.on("click", function() {
        ]);
                                this.close();
                            }.bind(this))
                        ),
                        this.$table.append(
                            $("<thead><th>用户</th><th>编辑数</th><th>增加字节数</th><th>删减字节数</th></thead>"),
                            this.$tbody
                        )
                    );
                    return this;
                };


        class ContributorDialog extends OO.ui.Dialog {
                ShowContributorDialog.prototype.getContributors = function() {
            $table = $('<table id="show-contributor-table" class="wikitable" />');
                    var self = this;
            $tbody = $("<tbody />");
                    return new Promise(function(resolve, reject) {
            got = false;
                        var api = new mw.Api();
 
                        var contributors = {};
            static static = {
                        var continueToken = "";
                ...super.static,
                        var prevSize = 0;
                name: "ShowContributor",
                        var params = {
                tagName: "div"
                            action: "query",
            };
                            format: "json",
 
                            prop: "revisions",
            initialize() {
                            titles: mw.config.get("wgPageName"),
                super.initialize();
                            rvprop: "user|size",
                this.$body.append(
                             rvlimit: "max",
                    $('<div id="show-contributor-header" />').append(
                             rvdir: "newer"
                        $('<div id="show-contributor-headline">本页贡献统计</div>'),
                         };
                        new OO.ui.IconWidget({
                        function fetchRevisions() {
                             icon: "close",
                            if (continueToken) params.rvcontinue = continueToken;
                             id: "show-contributor-close"
                            api.get(params).then(function(response) {
                         }).$element.on("click", () => this.close())
                                continueToken = response.continue ? response.continue.rvcontinue : undefined;
                    ),
                                var revisions = Object.values(response.query.pages)[0].revisions;
                    this.$table.append(
                                for (var i = 0; i < revisions.length; i++) {
                        $("<thead><th>用户</th><th>编辑数</th><th>增加字节数</th><th>删减字节数</th></thead>"),
                                    var user = revisions[i].user;
                        this.$tbody
                                    var size = revisions[i].size;
                    )
                                    contributors[user] = contributors[user] || [];
                );
                                    contributors[user].push(size - prevSize);
                return this;
                                    prevSize = size;
            }
                                }
 
                                if (continueToken) {
            async getContributors() {
                                    fetchRevisions();
                const api = new mw.Api();
                                } else {
                const users = {};
                                    resolve(contributors);
                let rvcontinue = "";
                                }
                 let lastSize = 0;
                            }).catch(function(error) {
                                mw.notify('获取编辑记录失败:' + error, { type: "error" });
                                reject(error);
                            });
                        }
                        fetchRevisions();
                    });
                 };


                 const params = {
                 ShowContributorDialog.prototype.addRow = function(tbody, data) {
                     action: "query",
                     var user = data.user;
                     format: "json",
                    var count = data.count;
                    prop: "revisions",
                    var add = data.add;
                    titles: mw.config.get("wgPageName"),
                    var remove = data.remove;
                    rvprop: "user|size",
                     tbody.append(
                    rvlimit: "max",
                        $("<tr />").append(
                     rvdir: "newer"
                            $("<td />").append(
                                $(`<a href="${mw.config.get("wgArticlePath").replace("$1", `User:${user}`)}" />`).text(user)
                            ),
                            `<td>${count}</td>`,
                            `<td>${add}</td>`,
                            `<td>${remove}</td>`
                        )
                     );
                 };
                 };


                 do {
                 ShowContributorDialog.prototype.showContributors = function(contributors) {
                     if (rvcontinue) params.rvcontinue = rvcontinue;
                     this.$tbody.empty();
                     try {
                     for (var user in contributors) {
                         const result = await api.get(params);
                         if (contributors.hasOwnProperty(user)) {
                        rvcontinue = result.continue?.rvcontinue;
                            var edits = contributors[user];
                        for (const { user, size } of Object.values(result.query.pages)[0].revisions) {
                            var add = edits.reduce(function(sum, delta) {
                             users[user] ||= [];
                                return delta > 0 ? sum + delta : sum;
                             users[user].push(size - lastSize);
                            }, 0);
                             lastSize = size;
                            var remove = edits.reduce(function(sum, delta) {
                                return delta < 0 ? sum + delta : sum;
                             }, 0);
                             this.addRow(this.$tbody, {
                                user: user,
                                count: edits.length,
                                add: add,
                                remove: remove
                             });
                         }
                         }
                    } catch (err) {
                        mw.notify(`获取编辑记录失败:${err}`, { type: "error" });
                        break;
                     }
                     }
                 } while (rvcontinue);
                    this.got = true;
                 };


                 return users;
                 var windowManager = new OO.ui.WindowManager({id:"show-contributor"});
            }
                $(document.body).append(windowManager.$element);
                var dialog = new ShowContributorDialog({size:"large"});
                windowManager.addWindows([dialog]);


            addRow($target, { user, count, add, remove }) {
                 var button = new OO.ui.ButtonWidget({
                 $target.append(
                     label:"本页贡献者",
                     $("<tr />").append(
                    icon:"search",
                        $("<td />").append(
                    flags:"progressive",
                            $(`<a href="${mw.config.get("wgArticlePath").replace("$1", `User:${user}`)}" />`).append(
                    id:"show-contributor-button"
                                `<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) {
                 var insertButton = function() {
                 this.$tbody.empty();
                     $("#show-contributor-button").detach();
                for (const user in data) {
                    var skin = mw.config.get("skin");
                     const edits = data[user];
                    if (skin === "citizen") {
                    this.addRow(this.$tbody, {
                        if (window.innerWidth >= 1120) {
                        user,
                            $(".page-actions").prepend(button.$element);
                        count: edits.length,
                        } else {
                        add: edits.reduce((sum, n) => n > 0 ? sum + n : sum, 0),
                            $(".firstHeading-container").append(button.$element);
                        remove: edits.reduce((sum, n) => n < 0 ? sum + n : sum, 0)
                        }
                    });
                    } else if (skin === "vector-2022") {
                }
                        $("header.mw-body-header.vector-page-titlebar").append(button.$element);
                this.got = true;
                     } else {
            }
                         $("#bodyContent").prepend(button.$element);
        }
 
        const dialogWindow = new ContributorDialog({ size: "large" });
        const windowManager = new OO.ui.WindowManager({ id: "show-contributor" });
        $(document.body).append(windowManager.$element);
        windowManager.addWindows([dialogWindow]);
 
        const $button = new OO.ui.ButtonWidget({
            label: "本页贡献者",
            icon: "search",
            flags: "progressive",
            id: "show-contributor-button"
        }).$element;
 
        const openDialog = async () => {
            if (!dialogWindow.got) {
                $button.find(".oo-ui-labelElement-label").text("正在查询");
                const data = await dialogWindow.getContributors();
                dialogWindow.showContributors(data);
                dialogWindow.$table.tablesorter();
                $button.find(".oo-ui-labelElement-label").text("本页贡献者");
            }
            windowManager.openWindow(dialogWindow);
        };
 
        $button.on("click", openDialog);
 
        const insertButton = () => {
            const skin = mw.config.get("skin");
            const width = window.innerWidth;
            $("#show-contributor-button").remove();
 
            if (skin === "citizen") {
                if (width <= 1119) {
                    $button.addClass("citizen-header-button");
                    const $header = $(".mw-header.citizen-header");
                     if ($header.length) {
                         $header.css("position", "relative").append($button);
                     }
                     }
                 } else if (width >= 1200) {
                 };
                    $button.removeClass("citizen-header-button");
                    $(".page-actions").prepend($button);
                }
            } else {
                $("#bodyContent").prepend($button);
            }
        };


        // 初始插入
                // 初始插入
        insertButton();
                insertButton();


        // 窗口尺寸变化时重新插入(节流)
                // 仅在断点穿越时更新插入位置
        let resizeTimer = null;
                var isWide = window.innerWidth >= 1120;
        $(window).on("resize", () => {
                $(window).on("resize", function() {
            clearTimeout(resizeTimer);
                    clearTimeout(window.__showContributorResizeTimer);
            resizeTimer = setTimeout(insertButton, 200);
                    window.__showContributorResizeTimer = setTimeout(function() {
        });
                        var nowWide = window.innerWidth >= 1120;
                        if (nowWide !== isWide) {
                            isWide = nowWide;
                            insertButton();
                        }
                    }, 200);
                });


    })());
                // 点击事件
                button.on("click", function() {
                    (function() {
                        if (!dialog.got) {
                            button.setLabel("正在查询");
                            dialog.getContributors().then(function(contributors) {
                                dialog.showContributors(contributors);
                                dialog.$table.tablesorter();
                                button.setLabel("本页贡献者");
                                windowManager.openWindow(dialog);
                            }).catch(function(error) {
                                console.error('获取贡献者数据失败:', error);
                                button.setLabel("本页贡献者");
                            });
                        } else {
                            windowManager.openWindow(dialog);
                        }
                    })();
                });
            });
        })();
    });
})();
})();

2025年6月17日 (二) 19:06的版本

// 原作者萌娘百科BearBin
//遵循BSD 3-Clause License使用代码
//全文请参见上方文档
//GitHub仓库地址:https://github.com/BearBin1215/MoegirlPedia
(function() {
    "use strict";
    $(function() {
        (function() {
            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.using([
                "mediawiki.api",
                "mediawiki.notification",
                "oojs-ui",
                "oojs-ui.styles.icons-interactions",
                "jquery.tablesorter"
            ]).then(function() {
                function ShowContributorDialog(config) {
                    OO.ui.Dialog.call(this, config);
                    this.$table = $('<table id="show-contributor-table" class="wikitable" />');
                    this.$tbody = $("<tbody />");
                    this.got = false;
                }
                OO.inheritClass(ShowContributorDialog, OO.ui.Dialog);
                ShowContributorDialog.static = ShowContributorDialog.static || {};
                ShowContributorDialog.static.name = "ShowContributor";
                ShowContributorDialog.static.tagName = "div";

                ShowContributorDialog.prototype.initialize = function() {
                    OO.ui.Dialog.prototype.initialize.call(this);
                    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", function() {
                                this.close();
                            }.bind(this))
                        ),
                        this.$table.append(
                            $("<thead><th>用户</th><th>编辑数</th><th>增加字节数</th><th>删减字节数</th></thead>"),
                            this.$tbody
                        )
                    );
                    return this;
                };

                ShowContributorDialog.prototype.getContributors = function() {
                    var self = this;
                    return new Promise(function(resolve, reject) {
                        var api = new mw.Api();
                        var contributors = {};
                        var continueToken = "";
                        var prevSize = 0;
                        var params = {
                            action: "query",
                            format: "json",
                            prop: "revisions",
                            titles: mw.config.get("wgPageName"),
                            rvprop: "user|size",
                            rvlimit: "max",
                            rvdir: "newer"
                        };
                        function fetchRevisions() {
                            if (continueToken) params.rvcontinue = continueToken;
                            api.get(params).then(function(response) {
                                continueToken = response.continue ? response.continue.rvcontinue : undefined;
                                var revisions = Object.values(response.query.pages)[0].revisions;
                                for (var i = 0; i < revisions.length; i++) {
                                    var user = revisions[i].user;
                                    var size = revisions[i].size;
                                    contributors[user] = contributors[user] || [];
                                    contributors[user].push(size - prevSize);
                                    prevSize = size;
                                }
                                if (continueToken) {
                                    fetchRevisions();
                                } else {
                                    resolve(contributors);
                                }
                            }).catch(function(error) {
                                mw.notify('获取编辑记录失败:' + error, { type: "error" });
                                reject(error);
                            });
                        }
                        fetchRevisions();
                    });
                };

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

                ShowContributorDialog.prototype.showContributors = function(contributors) {
                    this.$tbody.empty();
                    for (var user in contributors) {
                        if (contributors.hasOwnProperty(user)) {
                            var edits = contributors[user];
                            var add = edits.reduce(function(sum, delta) {
                                return delta > 0 ? sum + delta : sum;
                            }, 0);
                            var remove = edits.reduce(function(sum, delta) {
                                return delta < 0 ? sum + delta : sum;
                            }, 0);
                            this.addRow(this.$tbody, {
                                user: user,
                                count: edits.length,
                                add: add,
                                remove: remove
                            });
                        }
                    }
                    this.got = true;
                };

                var windowManager = new OO.ui.WindowManager({id:"show-contributor"});
                $(document.body).append(windowManager.$element);
                var dialog = new ShowContributorDialog({size:"large"});
                windowManager.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() {
                    (function() {
                        if (!dialog.got) {
                            button.setLabel("正在查询");
                            dialog.getContributors().then(function(contributors) {
                                dialog.showContributors(contributors);
                                dialog.$table.tablesorter();
                                button.setLabel("本页贡献者");
                                windowManager.openWindow(dialog);
                            }).catch(function(error) {
                                console.error('获取贡献者数据失败:', error);
                                button.setLabel("本页贡献者");
                            });
                        } else {
                            windowManager.openWindow(dialog);
                        }
                    })();
                });
            });
        })();
    });
})();