Jump to content

User:DreamRimmer/DraftNoCat.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>
mw.loader.using(['mediawiki.util', 'oojs-ui'], function () {
    $(() => {
        const DraftNoCat = {};
        window.DraftNoCat = DraftNoCat;
        DraftNoCat.config = {
            version: 1,
            debug: false
        };

        DraftNoCat.summary = "Disabling categories per [[WP:DRAFTNOCAT]]/[[WP:USERNOCAT]] (using [[User:DreamRimmer/DraftNoCat|DraftNoCat.js]])";

        DraftNoCat.run = async function (pages, dialog) {
            const api = new mw.Api();

            for (const page of pages) {
                const pageInfo = await api.get({
                    action: 'query',
                    titles: page.title,
                    prop: 'info',
                    formatversion: 2
                });
                if (pageInfo.query.pages[0].ns === 0) {
                    page.status = 'skipped (main space)';
                    updateProgress(page);
                    continue;
                }
                
                const editSummary = DraftNoCat.summary;
                page.status = 'editing...';
                updateProgress(page);
                try {
                    const response = await api.get({
                        action: 'query',
                        titles: page.title,
                        prop: 'revisions',
                        rvprop: 'content',
                        rvslots: 'main',
                        formatversion: 2
                    });
                    let text = response.query.pages[0].revisions[0].slots.main.content;
                    const draftCategoriesMatch = text.match(/\{\{Draft categories\|([\s\S]*?)\}\}/);
                    let newText = text;

                    if (draftCategoriesMatch) {
                        const draftCategoriesContent = draftCategoriesMatch[0];
                        const tempPlaceholder = `__DRAFT_CATEGORIES__`;
                        newText = text.replace(draftCategoriesMatch[0], tempPlaceholder);
                        newText = newText.replace(/\[\[\s*Category:/gi, '[[:Category:');
                        newText = newText.replace(tempPlaceholder, draftCategoriesContent);
                    } else {
                        newText = text.replace(/\[\[\s*Category:/gi, '[[:Category:');
                    }

                    if (newText !== text) {
                        await api.postWithEditToken({
                            action: 'edit',
                            title: page.title,
                            text: newText,
                            summary: editSummary,
                            minor: true
                        });
                        page.status = 'done';
                    } else {
                        page.status = 'no change';
                    }
                } catch (error) {
                    page.status = 'failed';
                }
                updateProgress(page);
                await new Promise(resolve => setTimeout(resolve, 1000));
            }

            setTimeout(() => dialog.close(), 2000);
        };

        function updateProgress(page) {
            const pageElement = document.getElementById(`page-${page.title}`);
            pageElement.innerHTML = `<li style="padding: 2px 0; margin: 2px 0;"><a href="/wiki/${page.title}" target="_blank">${page.title}</a> (<span style="color: ${page.status === 'done' ? 'green' : (page.status === 'failed' ? 'red' : 'black')}">${page.status}</span>)</li>`;
        }

        function openDialog(pages) {
            if (pages.length === 0) {
                alert('No members in the category.');
                return;
            }

            if ($('#draftNoCatDialog').length) {
                return;
            }

            function Dialog(config) {
                Dialog.super.call(this, config);
            }
            OO.inheritClass(Dialog, OO.ui.ProcessDialog);

            Dialog.static.name = 'draftNoCatDialog';
            Dialog.static.title = 'DraftNoCat';
            Dialog.static.actions = [
                { action: 'accept', label: 'Submit', flags: ['primary', 'progressive'] },
                { action: 'cancel', label: 'Cancel', flags: 'safe' }
            ];

            Dialog.prototype.initialize = function () {
                Dialog.super.prototype.initialize.apply(this, arguments);
                this.content = new OO.ui.PanelLayout({ padded: true, expanded: false });

                this.draftsFieldset = new OO.ui.FieldsetLayout({ label: 'Drafts', padded: true });
                const draftList = pages.map(page => 
                    `<li id="page-${page.title}" style="padding: 2px 0; margin: 2px 0;"><a href="/wiki/${page.title}" target="_blank">${page.title}</a></li>`
                ).join('');
                this.draftsFieldset.$element.append(`<ul>${draftList}</ul>`);

                this.content.$element.append(this.draftsFieldset.$element);
                this.$body.append(this.content.$element);
                this.$body.append('<div id="summary" style="padding: 5px 0; margin: 5px 0;"></div>');
            };

            Dialog.prototype.getActionProcess = function (action) {
                if (action === 'accept') {
                    this.draftsFieldset.setLabel('Progress');
                    return new OO.ui.Process(() => {
                        DraftNoCat.run(pages, this);
                    });
                }
                if (action === 'cancel') {
                    return new OO.ui.Process(() => this.close({ action }));
                }
                return Dialog.super.prototype.getActionProcess.call(this, action);
            };

            const windowManager = new OO.ui.WindowManager();
            $(document.body).append(windowManager.$element);
            const dialog = new Dialog({ size: 'medium', id: 'draftNoCatDialog' });
            windowManager.addWindows([dialog]);
            windowManager.openWindow(dialog);
        }

        $(document).ready(() => {
            if (mw.config.get('wgPageName') === 'Category:AfC_submissions_with_categories') {
                const link = mw.util.addPortletLink('p-cactions', '#', 'DNC', 'ca-dnc', 'Draft no cats');
                $(link).click(async function (event) {
                    event.preventDefault();
                    const api = new mw.Api();
                    const response = await api.get({
                        action: 'query',
                        list: 'categorymembers',
                        cmtitle: 'Category:AfC_submissions_with_categories',
                        cmlimit: 'max',
                        formatversion: 2
                    });
                    const pages = response.query.categorymembers.map(member => ({ title: member.title, status: 'waiting' }));
                    openDialog(pages);
                });
            }
        });
    });
});
//</nowiki>