跳转到内容

User:What7what8/CommentHistoryTool a.js

维基百科,自由的百科全书
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
// Wikipedia Discussion History Gadget
$(function() {
    mw.loader.using('ext.gadget.HanAssist').then(require => {
        const { conv } = require('ext.gadget.HanAssist');

        // Load necessary styles
        mw.loader.load(`https://zh.wikipedia.org/w/load.php?lang=${mw.config.get("wgPageViewLanguage")}&modules=ext.visualEditor.diffPage.init.styles%7Cmediawiki.diff.styles&only=styles&skin=${mw.config.get('skin')}`, 'text/css');

        // Append history button next to reply buttons
        $(".ext-discussiontools-init-replylink-buttons").after(`
            <span class="tool-init-comment-historybutton oo-ui-widget oo-ui-buttonElement oo-ui-buttonElement-frameless oo-ui-iconElement oo-ui-labelElement oo-ui-flaggedElement-progressive oo-ui-buttonWidget" style="display: none;">
                <div class="tool-init-comment-historybutton-tooltip" data-hasrun="false" haspreview="false" oldest_old_id="-1"></div>
                <a class="oo-ui-buttonElement-button" role="button" tabindex="0" rel="nofollow">
                    <span class="oo-ui-iconElement-icon oo-ui-icon-clock"></span>
                    <span class="oo-ui-labelElement-label">${conv({ hans: '历史', hant: '歷史' })}</span>
                </a>
            </span>`
        );

        // Show button when AJAX requests complete
        $(document).ajaxStop(() => $(".tool-init-comment-historybutton").show());

        // Tooltip Styling
        $(".tool-init-comment-historybutton-tooltip").css({
            display: "none",
            width: "auto",
            backgroundColor: "black",
            color: "#fff",
            borderRadius: "6px",
            padding: "5px 0",
            position: "absolute",
            zIndex: "1",
            flexWrap: "wrap",
            justifyContent: "center",
            alignItems: "center"
        });

        // Utility Functions
        const hashCode = str => str.split("").reduce((a, b) => ((a << 5) - a) + b.charCodeAt(0), 0);
        
        function updateTooltipMessage(tooltip, message) {
            tooltip.text(conv({ hans: message, hant: message }));
        }

        function findComment(html, commentId) {
            const regex = new RegExp(`${commentId}"></span>([\\s\\S]*?)${commentId}`);
            return regex.exec(html.replaceAll(' class="userlink"', '').trim());
        }

        function addPreviewToElement(element) {
            const url = element.find("a").attr("href");
            element.attr("haspreview", "true");

            $.get(url, html => {
                const diff = $('<div/>').html(html).find('.diff').css({ fontSize: "10px" });
                element.append(`<div class="diff-comment-preview" style="display: none;">${diff[0].outerHTML}</div>`);
                
                element.hover(
                    () => element.find(".diff-comment-preview").show(),
                    () => element.find(".diff-comment-preview").hide()
                );
            });
        }

        function removeDuplicateComments(element, comment) {
            const commentHash = hashCode(comment);
            element.find('*').each(function() {
                if ($(this).attr("data-old_comment") === commentHash) {
                    $(this).remove();
                } else {
                    if ($(this).attr("haspreview") !== "true") addPreviewToElement($(this));
                }
            });
        }

        function addHistoryItem(tooltip, item) {
            const displayItem = $(`
                <div data-old_id="${item.old_id}" data-old_comment="${hashCode(item.old_comment)}">
                    <div class="date-item">${item.timestamp.toISOString()}&nbsp;&nbsp;</div>
                    <a href="${item.url}">URL</a>
                </div>
            `);

            let before = null;
            tooltip.children().each(function () {
                if (parseInt($(this).attr("data-old_id"), 10) < item.old_id) {
                    before = $(this);
                    return false;
                }
            });

            before ? displayItem.insertBefore(before) : tooltip.append(displayItem);
            removeDuplicateComments(tooltip, item.comment);
        }

        function fetchOldComment(edit, comment, commentId, tooltip) {
            const oldId = edit.id;
            if (parseInt(tooltip.attr("oldest_old_id"), 10) > oldId) return;

            new mw.Api().get({
                action: "parse",
                format: "json",
                formatversion: 2,
                oldid: oldId,
                prop: "text",
                useskin: mw.config.get('skin')
            }).done(oldPageJson => {
                if (oldPageJson.error) return;

                const oldPage = oldPageJson.parse.text;
                updateTooltipMessage(tooltip, '正在努力搜寻中');

                const oldComment = findComment(oldPage, commentId);
                if (!oldComment) {
                    tooltip.attr("oldest_old_id", oldId);
                    return;
                }

                if (comment !== oldComment[0]) {
                    addHistoryItem(tooltip, {
                        isDiff: true,
                        url: `https://${mw.config.get("wgServerName")}/w/index.php?title=${encodeURIComponent(mw.config.get("wgPageName"))}&diff=next&oldid=${oldId}`,
                        timestamp: new Date(edit.timestamp),
                        old_id: oldId,
                        comment,
                        old_comment: oldComment[0]
                    });
                }
            });
        }

        function searchHistory(maxSearch, comment, commentId, tooltip) {
            if (maxSearch >= 100) return;

            if (window.wikipage_history_list.length >= (maxSearch + 1) * 20) {
                for (let i = maxSearch * 20; i < (maxSearch + 1) * 20; i++) {
                    fetchOldComment(window.wikipage_history_list[i], comment, commentId, tooltip);
                }
                searchHistory(maxSearch + 1, comment, commentId, tooltip);
            } else {
                $.get(window.wikipage_history_url, data => {
                    window.wikipage_history_list = window.wikipage_history_list.concat(data.revisions);
                    data.revisions.forEach(edit => fetchOldComment(edit, comment, commentId, tooltip));

                    if (data.older) {
                        window.wikipage_history_url = data.older;
                        searchHistory(maxSearch + 1, comment, commentId, tooltip);
                    }
                });
            }
        }

        $(".tool-init-comment-historybutton").click(function() {
            const tooltip = $(this).find(".tool-init-comment-historybutton-tooltip");
            tooltip.toggle();

            if (tooltip.attr("data-hasrun") === "false") {
                tooltip.attr("data-hasrun", "true");
                const commentId = $(this).prev(".ext-discussiontools-init-replylink-buttons").attr("data-mw-thread-id");
                const comment = findComment($('html').html(), commentId)[0];

                tooltip.append(conv({ hans: '正在努力搜寻中', hant: '正在努力搜尋中' }));

                window.wikipage_history_list = window.wikipage_history_list || [];
                window.wikipage_history_url = `https://${mw.config.get("wgServerName")}/w/rest.php/v1/page/${encodeURIComponent(mw.config.get("wgPageName"))}/history`;

                searchHistory(0, comment, commentId, tooltip);
            }
        });
    });
});