Jump to content

User:DreamRimmer/DeletedMetaData.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
//<nowiki>
(function () {
    function formatDate(date) {
        const day = date.getUTCDate();
        const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
        const month = monthNames[date.getUTCMonth()];
        const year = date.getUTCFullYear();
        let hours = date.getUTCHours();
        const minutes = date.getUTCMinutes();
        const seconds = date.getUTCSeconds();
        const ampm = hours >= 12 ? 'PM' : 'AM';
        hours = hours % 12;
        if (hours === 0) hours = 12;
        const minutesStr = minutes.toString().padStart(2, '0');
        const secondsStr = seconds.toString().padStart(2, '0');
        return `${day} ${month} ${year}, ${hours}:${minutesStr}:${secondsStr} ${ampm} (UTC)`;
    }

    mw.loader.using(['mediawiki.api', 'oojs-ui', 'mediawiki.util']).then(function () {
        function addPortletLink() {
            mw.util.addPortletLink(
                'p-tb',
                '#',
                'View metadata of deleted revisions',
                'ca-show-deleted-revisions',
                'View metadata of deleted revisions'
            );

            document.getElementById('ca-show-deleted-revisions').addEventListener('click', function (e) {
                e.preventDefault();
                const pageTitle = mw.config.get('wgPageName');
                fetchRevisions(pageTitle);
            });
        }

        function fetchRevisions(pageTitle, continuation) {
            const params = {
                action: 'query',
                prop: 'deletedrevisions',
                titles: pageTitle,
                drvprop: 'user|timestamp|tags|size',
                drvlimit: 'max',
                formatversion: 2
            };
            if (continuation) {
                params.drvcontinue = continuation;
            }
            new mw.Api().get(params).done(function (data) {
                const pageData = data.query.pages[0];
                if (pageData.deletedrevisions) {
                    const cont = data.continue ? data.continue.drvcontinue : null;
                    if (window.revisionDialog && window.revisionDialog.isOpen()) {
                        window.revisionDialog.appendRevisions(pageData.deletedrevisions);
                        window.revisionDialog.totalCount += pageData.deletedrevisions.length;
                        window.revisionDialog.$countDisplay.text('Total revisions loaded: ' + window.revisionDialog.totalCount);
                        window.revisionDialog.continuation = cont;
                        if (!cont && window.revisionDialog.$nextButton) {
                            window.revisionDialog.$nextButton.remove();
                            window.revisionDialog.$nextButton = null;
                        }
                    } else {
                        showDialog(pageData.deletedrevisions, pageData.title || pageTitle, cont);
                    }
                } else {
                    new OO.ui.Alert('No deleted revisions found for this page.', { type: 'error' }).show();
                }
            }).fail(function (error) {
                new OO.ui.Alert('Error loading revisions: ' + error, { type: 'error' }).show();
            });
        }

        function showDialog(revisions, title, continuation) {
            const RevisionDialog = function (config) {
                RevisionDialog.super.call(this, config);
            };
            OO.inheritClass(RevisionDialog, OO.ui.ProcessDialog);
            RevisionDialog.static.name = 'revisionDialog';
            RevisionDialog.static.title = 'Deleted revisions: ' + title;
            RevisionDialog.static.actions = [
                { action: 'close', icon: 'close', flags: ['safe'] }
            ];

            RevisionDialog.prototype.initialize = function () {
                RevisionDialog.super.prototype.initialize.call(this);
                this.pageTitle = title;
                this.continuation = continuation;
                this.totalCount = revisions.length;
                this.$countDisplay = $('<div>')
                    .css({ 'margin-top': '1em', 'margin-left': '1em', 'font-weight': 'bold' })
                    .text('Total revisions: ' + this.totalCount);
                this.$body.append(this.$countDisplay);
                const tablePanel = new OO.ui.PanelLayout({ padded: true, expanded: false });
                this.$body.append(tablePanel.$element);
                const $table = $('<table>')
                    .addClass('wikitable')
                    .css({ 'width': '100%', 'border-collapse': 'collapse', 'background-color': 'white', '--background-color-neutral-subtle': 'white' });
                $table.append($('<thead>').append(
                    $('<tr>').append(
                        $('<th>').text('User').css('width', '25%'),
                        $('<th>').text('Date/Time').css('width', '35%'),
                        $('<th>').text('Size').css('width', '15%'),
                        $('<th>').text('Tags').css('width', '40%')
                    )
                ));
                this.$tbody = $('<tbody>');
                $table.append(this.$tbody);
                tablePanel.$element.append($table);
                this.appendRevisions(revisions);
                if (this.continuation) {
                    this.$nextButton = $('<button>')
                        .addClass('mw-ui-button')
                        .text('Next')
                        .css({ 'margin-top': '1em' });
                    this.$body.append($('<div>').append(this.$nextButton));
                    this.$nextButton.on('click', () => {
                        this.loadMore();
                    });
                }
            };

            RevisionDialog.prototype.appendRevisions = function (revisions) {
                revisions.forEach(rev => {
                    const dateStr = formatDate(new Date(rev.timestamp));
                    const userUrl = mw.util.getUrl('User:' + rev.user);
                    const $userLink = $('<a>').attr('href', userUrl).text(rev.user);
                    const $tr = $('<tr>').append(
                        $('<td>').append($userLink),
                        $('<td>').text(dateStr),
                        $('<td>').text(rev.size.toLocaleString() + ' bytes'),
                        $('<td>').text((rev.tags && rev.tags.length > 0) ? rev.tags.join(', ') : '—')
                    );
                    this.$tbody.append($tr);
                });
            };

            RevisionDialog.prototype.loadMore = function () {
                if (!this.continuation) return;
                if (this.$nextButton) {
                    this.$nextButton.prop('disabled', true).text('Loading...');
                }
                const params = {
                    action: 'query',
                    prop: 'deletedrevisions',
                    titles: this.pageTitle,
                    drvprop: 'user|timestamp|tags|size',
                    drvlimit: 'max',
                    formatversion: 2,
                    drvcontinue: this.continuation
                };
                new mw.Api().get(params).done((data) => {
                    const pageData = data.query.pages[0];
                    if (pageData.deletedrevisions) {
                        this.appendRevisions(pageData.deletedrevisions);
                        this.totalCount += pageData.deletedrevisions.length;
                        this.$countDisplay.text('Total revisions loaded: ' + this.totalCount);
                    }
                    this.continuation = data.continue ? data.continue.drvcontinue : null;
                    if (this.continuation) {
                        if (this.$nextButton) {
                            this.$nextButton.prop('disabled', false).text('Next');
                        }
                    } else {
                        if (this.$nextButton) {
                            this.$nextButton.remove();
                            this.$nextButton = null;
                        }
                    }
                }).fail((error) => {
                    new OO.ui.Alert('Error loading more revisions: ' + error, { type: 'error' }).show();
                    if (this.$nextButton) {
                        this.$nextButton.prop('disabled', false).text('Next');
                    }
                });
            };

            RevisionDialog.prototype.getActionProcess = function (action) {
                return action === 'close' ?
                    new OO.ui.Process(() => this.close()) :
                    RevisionDialog.super.prototype.getActionProcess.call(this, action);
            };

            const windowManager = new OO.ui.WindowManager();
            $('body').append(windowManager.$element);
            const dialog = new RevisionDialog({ size: 'larger' });
            windowManager.addWindows([dialog]);
            windowManager.openWindow(dialog).then(openedDialog => {
                openedDialog.get$frame().css({
                    width: '90%',
                    maxWidth: '1200px',
                    maxHeight: '80vh',
                    margin: '2rem auto'
                });
                openedDialog.$body.css('overflow', 'auto');
                window.revisionDialog = openedDialog;
            });
        }

        if (document.querySelector('li[data-mw-logaction^="delete/"]')) {
            addPortletLink();
        } else {
            const pageTitle = mw.config.get('wgPageName');
            const params = {
                action: 'query',
                prop: 'deletedrevisions',
                titles: pageTitle,
                drvprop: 'user|timestamp|tags|size',
                drvlimit: 1,
                formatversion: 2
            };
            new mw.Api().get(params).done(function (data) {
                const pageData = data.query.pages[0];
                if (pageData.deletedrevisions && pageData.deletedrevisions.length > 0) {
                    addPortletLink();
                }
            }).fail(function (error) {
                console.error('Error checking for deleted revisions: ' + error);
            });
        }
    });
})();
//</nowiki>