MediaWiki:Common.js

From MDrivenWiki
Revision as of 23:28, 7 July 2024 by Edgar (talk | contribs)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
This page was edited 146 days ago on 08/26/2024. What links here
// ==UserScript==
// @name        MediaWiki Clean Delete
// @namespace   MediaWikiScripts
// @description Adds a 'Clean Delete' action link to pages for admins to delete pages and clean up incoming links and redirects.
// ==/UserScript==

mw.loader.using(['mediawiki.api', 'mediawiki.util', 'jquery', 'bootstrap'], function () {
    function addCleanDeleteLink() {
        if (mw.config.get('wgUserGroups').indexOf('sysop') !== -1) {
            if ($('#ca-cleandelete').length === 0) {
                var $link = $('<div>').attr('id', 'ca-cleandelete').attr('class', 'mw-list-item').append(
                    $('<a>').attr('href', '#').attr('class', 'ca-cleandelete').text('Clean Delete').click(function (e) {
                        e.preventDefault();
                        gatherAllDecisions(mw.config.get('wgPageName'));
                    })
                );
                $('#p-actions .tab-group').append($link);
            }
        }
    }

    function gatherAllDecisions(pageTitle) {
        var decisions = {};
        showModal('Handle Links and Redirects', `
            <div class="form-group">
                <label>Specify how you would like to handle all incoming links and redirects:</label>
                <select id="link-handling-select" class="form-control">
                    <option value="delete">Delete Links and Redirects</option>
                    <option value="change">Change Target of Links and Redirects</option>
                </select>
            </div>
        `, function () {
            var choice = $('#link-handling-select').val();
            if (choice === 'change') {
                showModal('Specify New Target', `
                    <div class="form-group">
                        <label>Enter the new target page name to update all links and redirects:</label>
                        <input type="text" id="new-target-input" class="form-control" placeholder="Enter new target">
                    </div>
                `, function () {
                    decisions.links = $('#new-target-input').val();
                    confirmDeletion(pageTitle, decisions);
                });
            } else {
                decisions.links = '';
                confirmDeletion(pageTitle, decisions);
            }
        });
    }

    function confirmDeletion(pageTitle, decisions) {
        showModal('Confirm Page Deletion', `
            <p>Are you sure you want to delete "${pageTitle}" after handling all links and redirects?</p>
        `, function () {
            decisions.deletion = true;
            showLoadingDialog('Performing Cleanup', function (updateLoadingText) {
                executeAllActions(pageTitle, decisions, function () {
                    location.reload();
                }, updateLoadingText);
            });
        });
    }

    function showModal(title, body, onConfirm) {
        var modal = $(`
            <div class="modal fade" tabindex="-1" role="dialog">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title">${title}</h5>
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <div class="modal-body">
                            ${body}
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                            <button type="button" class="btn btn-primary">Confirm</button>
                        </div>
                    </div>
                </div>
            </div>
        `);

        modal.find('.btn-primary').click(function () {
            onConfirm();
            modal.modal('hide');
        });

        modal.on('hidden.bs.modal', function () {
            modal.remove();
        });

        $('body').append(modal);
        modal.modal('show');
    }

    function showLoadingDialog(message, callback) {
        var modal = $(`
            <div class="modal fade" tabindex="-1" role="dialog">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title">Performing Cleanup</h5>
                        </div>
                        <div class="modal-body">
                            <p id="loading-text">${message}</p>
                        </div>
                    </div>
                </div>
            </div>
        `);

        $('body').append(modal);
        modal.modal('show');

        callback(function (text) {
            $('#loading-text').text(text);
            console.log(text); // Log progress
        });
    }

    function executeAllActions(pageTitle, decisions, callback, updateLoadingText) {
        var api = new mw.Api();

        function handleLinksAndRedirects(action, newTarget, next) {
            updateLoadingText(action === 'update' ? 'Updating all links and redirects...' : 'Removing all links and redirects...');
            api.get({
                action: 'query',
                list: 'backlinks',
                bltitle: pageTitle,
                bllimit: 'max'
            }).done(function (data) {
                if (data.query.backlinks) {
                    var promises = data.query.backlinks.map(function (link) {
                        return new Promise(function (resolve) {
                            if (action === 'update') {
                                updateLink(link.title, newTarget, api).then(resolve);
                            } else {
                                removeLink(link.title, api).then(resolve);
                            }
                        });
                    });
                    Promise.all(promises).then(function () {
                        updateLoadingText(action === 'update' ? 'All links and redirects updated.' : 'All links and redirects removed.');
                        next();
                    });
                } else {
                    next();
                }
            }).fail(function (error) {
                console.error('Error fetching backlinks:', error);
                updateLoadingText('Error fetching backlinks: ' + error);
                next();
            });
        }

        function updateLink(pageTitle, newTarget, api) {
            return api.postWithToken('csrf', {
                action: 'edit',
                title: pageTitle,
                text: '#REDIRECT [[' + newTarget + ']]',
                summary: 'Updated redirect to new target [[' + newTarget + ']]'
            }).fail(function (error) {
                console.error('Error updating link:', error);
            });
        }

        function removeLink(pageTitle, api) {
            return api.postWithToken('csrf', {
                action: 'edit',
                title: pageTitle,
                text: '',
                summary: 'Removed link to [[' + pageTitle + ']]'
            }).fail(function (error) {
                console.error('Error removing link:', error);
            });
        }

        function performDeletion(pageTitle, next) {
            updateLoadingText('Deleting the page...');
            api.postWithToken('csrf', {
                action: 'delete',
                title: pageTitle,
                reason: 'Automated clean delete by admin'
            }).done(function () {
                updateLoadingText('Page deleted.');
                next();
            }).fail(function (error) {
                console.error('Error during clean deletion:', error);
                updateLoadingText('Error during clean deletion: ' + error);
                next();
            });
        }

        var tasks = [
            function (resolve) {
                if (decisions.links === '') {
                    handleLinksAndRedirects('remove', '', resolve);
                } else {
                    handleLinksAndRedirects('update', decisions.links, resolve);
                }
            },
            function (resolve) {
                if (decisions.deletion) {
                    performDeletion(pageTitle, resolve);
                } else {
                    resolve();
                }
            }
        ];

        (function executeTasks(i) {
            if (i < tasks.length) {
                tasks[i](function () {
                    executeTasks(i + 1);
                });
            } else {
                callback();
            }
        })(0);
    }

    mw.hook('wikipage.content').add(addCleanDeleteLink);
});
This page was edited 146 days ago on 08/26/2024. What links here