Jump to content

User:Eejit43/scripts/ajax-undo.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Eejit43 (talk | contribs) at 03:49, 17 February 2023 (create user script). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
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>
/* global mw, importStylesheet */

const stages = {
    AWAITING_CLICK: 0,
    AWAITING_CONFIRMATION: 1,
    AWAITING_RELOAD: 2
};

mw.loader.using(['mediawiki.util', 'mediawiki.notification'], () => {
    if (mw.config.get('wgAction') !== 'history') return;

    importStylesheet('User:Eejit43/styles/ajax-undo.css');

    document.querySelectorAll('.mw-history-undo').forEach((undoSpan) => {
        const undoUrl = new URL(undoSpan.querySelector('a').href);

        const span = document.createElement('span');

        let stage = stages.AWAITING_CLICK;

        const ajaxUndoLink = document.createElement('a');
        ajaxUndoLink.textContent = 'ajax undo';
        ajaxUndoLink.href = undoUrl.href;
        ajaxUndoLink.addEventListener('click', async (event) => {
            event.preventDefault();

            if (stage === stages.AWAITING_CLICK) {
                stage = stages.AWAITING_CONFIRMATION;

                reasonInput.style.display = 'inline';

                ajaxUndoLink.textContent = 'confirm ajax undo';
            } else if (stage === stages.AWAITING_CONFIRMATION) {
                stage = stages.AWAITING_RELOAD;
                loadingSpinner.style.display = 'inline-block';
                ajaxUndoLink.style.color = 'gray';
                reasonInput.disabled = true;

                const undoId = undoUrl.searchParams.get('undo');
                const undoAfter = undoUrl.searchParams.get('undoafter');

                const revisionUser = undoSpan.closest('li').querySelector('.mw-userlink bdi').textContent;

                try {
                    await new mw.Api().postWithEditToken({
                        action: 'edit',
                        title: mw.config.get('wgPageName'),
                        undo: undoId,
                        undoafter: undoAfter,
                        summary: `Undid revision ${undoId} by [[Special:Contributions/${revisionUser}|${revisionUser}]] ([[User talk:${revisionUser}|talk]])${reasonInput.value ? `: ${reasonInput.value}` : ''}`
                    });
                } catch (error) {
                    console.error(error);
                    return mw.notification.notify(new mw.Api().getErrorMessage(error), { type: 'error' });
                }

                mw.notification.notify('Revision successfully undone, reloading...', { type: 'success' });
                window.location.reload();
            }
        });

        span.appendChild(ajaxUndoLink);

        const loadingSpinner = document.createElement('span');
        loadingSpinner.id = 'ajax-undo-loading';
        loadingSpinner.style.display = 'none';

        span.appendChild(loadingSpinner);

        const reasonInput = document.createElement('input');
        reasonInput.type = 'text';
        reasonInput.id = 'ajax-undo-reason';
        reasonInput.placeholder = 'Insert reason here...';
        reasonInput.addEventListener('keydown', (event) => {
            if (event.key === 'Enter') ajaxUndoLink.click();
        });

        span.appendChild(reasonInput);

        undoSpan.parentElement.after(span);
    });
});

// </nowiki>