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

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

MediaWiki界面页面
第22行: 第22行:
     text-align: center;
     text-align: center;
     top: 0;
     top: 0;
    z-index: 1;
}
}
#show-contributor-headline {
#show-contributor-headline {
第48行: 第49行:
     display: inline-flex;
     display: inline-flex;
     align-items: center;
     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;
    }
}
}
`);
`);
第186行: 第197行:
             if (skin === "citizen") {
             if (skin === "citizen") {
                 if (width <= 1119) {
                 if (width <= 1119) {
                     $(".citizen-page-heading").append($button);
                     $button.addClass("citizen-header-button");
                    const $header = $(".mw-header.citizen-header");
                    if ($header.length) {
                        $header.css("position", "relative").append($button);
                    }
                 } else if (width >= 1200) {
                 } else if (width >= 1200) {
                    $button.removeClass("citizen-header-button");
                     $(".page-actions").prepend($button);
                     $(".page-actions").prepend($button);
                 }
                 }
第202行: 第218行:
         $(window).on("resize", () => {
         $(window).on("resize", () => {
             clearTimeout(resizeTimer);
             clearTimeout(resizeTimer);
             resizeTimer = setTimeout(insertButton, 200); // 节流,避免高频触发
             resizeTimer = setTimeout(insertButton, 200);
         });
         });


     })());
     })());
})();
})();

2025年6月11日 (三) 12:02的版本

(() => {
    "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;
    z-index: 1;
}
#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 {
    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([
            "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 />");
            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><th>用户</th><th>编辑数</th><th>增加字节数</th><th>删减字节数</th></thead>"),
                        this.$tbody
                    )
                );
                return this;
            }

            async getContributors() {
                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 result = await api.get(params);
                        rvcontinue = result.continue?.rvcontinue;
                        for (const { user, size } of Object.values(result.query.pages)[0].revisions) {
                            users[user] ||= [];
                            users[user].push(size - lastSize);
                            lastSize = size;
                        }
                    } catch (err) {
                        mw.notify(`获取编辑记录失败:${err}`, { type: "error" });
                        break;
                    }
                } while (rvcontinue);

                return users;
            }

            addRow($target, { user, count, add, remove }) {
                $target.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 edits = data[user];
                    this.addRow(this.$tbody, {
                        user,
                        count: edits.length,
                        add: edits.reduce((sum, n) => n > 0 ? sum + n : sum, 0),
                        remove: edits.reduce((sum, n) => n < 0 ? sum + n : sum, 0)
                    });
                }
                this.got = true;
            }
        }

        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();

        // 窗口尺寸变化时重新插入(节流)
        let resizeTimer = null;
        $(window).on("resize", () => {
            clearTimeout(resizeTimer);
            resizeTimer = setTimeout(insertButton, 200);
        });

    })());
})();