Jump to content

User:PieWriter/vfd.js

From Wikiquote, the free quote compendium

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)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// <nowiki>
mw.loader.using(['mediawiki.api', 'mediawiki.util', 'oojs-ui'], function () {

    function getOrdinal(n) {
        var s = ["th", "st", "nd", "rd"];
        var v = n % 100;
        return n + (s[(v - 20) % 10] || s[v] || s[0]);
    }

    function getVfdSubpageTitle(api, pageName) {
        var baseTitle = "Wikiquote:Votes for deletion/" + pageName;

        return api.get({
            action: 'query',
            titles: baseTitle,
            formatversion: 2
        }).then(function (data) {

            var page = data.query.pages[0];

            if (page.missing) {
                return baseTitle;
            }

            function checkNext(n) {
                var candidate =
                    baseTitle + " (" + getOrdinal(n) + " nomination)";

                return api.get({
                    action: 'query',
                    titles: candidate,
                    formatversion: 2
                }).then(function (res) {

                    var p = res.query.pages[0];

                    if (p.missing) {
                        return candidate;
                    }

                    return checkNext(n + 1);
                });
            }

            return checkNext(2);
        });
    }

    function openDialog() {

        var windowManager = new OO.ui.WindowManager();
        $(document.body).append(windowManager.$element);

        var dialog = new OO.ui.MessageDialog();
        windowManager.addWindows([dialog]);

        var radioSelect = new OO.ui.RadioSelectWidget({
            items: [
                new OO.ui.RadioOptionWidget({
                    data: 'spam',
                    label: 'Spam'
                }),
                new OO.ui.RadioOptionWidget({
                    data: 'vandalism',
                    label: 'Vandalism'
                }),
                new OO.ui.RadioOptionWidget({
                    data: 'empty',
                    label: 'Empty page'
                }),
                new OO.ui.RadioOptionWidget({
                    data: 'notable',
                    label: 'Not notable'
                }),
                new OO.ui.RadioOptionWidget({
                    data: 'oop',
                    label: 'Out of project scope'
                }),
                new OO.ui.RadioOptionWidget({
                    data: 'custom',
                    label: 'Custom reason'
                })
            ]
        });

        var customInput = new OO.ui.MultilineTextInputWidget({
            placeholder: 'Enter custom reason...',
            autosize: true
        });

        var container = new OO.ui.PanelLayout({
            padded: true,
            expanded: false
        });

        container.$element.append(
            new OO.ui.LabelWidget({
                label: 'Select a reason:'
            }).$element,
            radioSelect.$element,
            customInput.$element
        );

        windowManager.openWindow(dialog, {
            title: 'Votes for Deletion',
            message: container.$element,
            actions: [
                {
                    action: 'submit',
                    label: 'Nominate',
                    flags: ['primary', 'progressive']
                },
                {
                    action: 'cancel',
                    label: 'Cancel',
                    flags: 'safe'
                }
            ]
        }).closed.then(function (data) {

            if (!data || data.action !== 'submit') {
                return;
            }

            var selected = radioSelect.findSelectedItem();

            if (!selected) {
                mw.notify('Select a reason', {
                    type: 'error'
                });
                return;
            }

            var reasonMap = {
                spam: 'Spam page',
                vandalism: 'Vandalism',
                empty: 'Empty page',
                notable: 'Not notable',
                oop: 'Out of project scope'
            };

            var reason = selected.getData() === 'custom'
                ? customInput.getValue()
                : reasonMap[selected.getData()];

            if (!reason) {
                mw.notify('Provide a reason', {
                    type: 'error'
                });
                return;
            }

            var titleObj = new mw.Title(
                mw.config.get('wgPageName')
            );

            var pageName = titleObj.getPrefixedText();
            var api = new mw.Api();
            var vfdSubpage = '';

            getVfdSubpageTitle(api, pageName)

                .then(function (targetSubpage) {

                    vfdSubpage = targetSubpage;

                    return api.get({
                        action: 'query',
                        prop: 'revisions',
                        titles: pageName,
                        rvprop: 'content',
                        formatversion: 2
                    });

                })

                .then(function (data) {

                    var page = data.query.pages[0];

                    var content =
                        (page.revisions && page.revisions[0])
                            ? page.revisions[0].content
                            : "";

                    if (content.includes('{{vfd-new')) {
                        throw new Error("Already nominated");
                    }

                    return api.postWithToken('csrf', {
                        action: 'edit',
                        title: pageName,
                        text: "{{vfd-new}}\n" +
                            content.replace(/^\s+/, ''),
                        summary:
                            'Adding VFD with [[User:PieWriter/vfd|tool]]',
                        watchlist: 'watch'
                    });

                })

                .then(function () {

                    return api.postWithToken('csrf', {
                        action: 'edit',
                        title: vfdSubpage,
                        text:
                            "{{subst:vfd-new2|pg=" +
                            pageName +
                            "|text=" +
                            reason +
                            " — ~~~~}}",
                        summary: "VfD: " + pageName,
                        watchlist: 'watch'
                    });

                })

                /*
                 * Add the nominator vote.
                 *
                 * The old code attempted to insert the vote before
                 * the "Vote closes" line. This caused the vote to
                 * appear above the closure date.
                 *
                 * The vote is now added after the generated VFD
                 * content, leaving the closure date untouched.
                 */

                .then(function () {

                    return api.get({
                        action: 'query',
                        prop: 'revisions',
                        titles: vfdSubpage,
                        rvprop: 'content',
                        formatversion: 2
                    }).then(function (data) {

                        var page = data.query.pages[0];

                        if (
                            !page.revisions ||
                            !page.revisions[0]
                        ) {
                            throw new Error(
                                "Could not retrieve VFD page"
                            );
                        }

                        var text =
                            page.revisions[0].content;

                        var voteText =
                            ": '''Delete''' as nominator ~~~~";

                        /*
                         * Remove trailing whitespace and append
                         * the nominator vote.
                         */
                        var newText =
                            text.replace(/\s+$/, '') +
                            "\n" +
                            voteText;

                        return api.postWithToken('csrf', {
                            action: 'edit',
                            title: vfdSubpage,
                            text: newText,
                            summary: "Adding nominator vote",
                            watchlist: 'watch'
                        });

                    });

                })

                .then(function () {

                    return api.get({
                        action: 'query',
                        prop: 'revisions',
                        titles: "Wikiquote:Votes for deletion",
                        rvprop: 'content',
                        formatversion: 2
                    }).then(function (data) {

                        var page = data.query.pages[0];

                        if (
                            !page.revisions ||
                            !page.revisions[0]
                        ) {
                            throw new Error(
                                "Could not retrieve main VFD page"
                            );
                        }

                        var text =
                            page.revisions[0].content;

                        var cleanText =
                            text.replace(/\s+$/, '');

                        return api.postWithToken('csrf', {
                            action: 'edit',
                            title: "Wikiquote:Votes for deletion",
                            text:
                                cleanText +
                                "\n{{" +
                                vfdSubpage +
                                "}}",
                            summary:
                                "Adding " +
                                pageName +
                                " VfD entry",
                            watchlist: 'watch'
                        });

                    });

                })

                .then(function () {

                    mw.notify(
                        'VfD nomination complete',
                        {
                            type: 'success'
                        }
                    );

                })

                .catch(function (err) {

                    mw.notify(
                        err.message ||
                        'Error during VFD',
                        {
                            type: 'error'
                        }
                    );

                });

        });
    }

    function addLink() {

        if (mw.config.get('wgNamespaceNumber') < 0) {
            return;
        }

        var link = mw.util.addPortletLink(
            'p-cactions',
            '#',
            'VFD',
            'ca-vfd',
            'Nominate for deletion'
        );

        if (!link) {
            return;
        }

        $(link).on('click', function (e) {

            e.preventDefault();
            openDialog();

        });
    }

    $(addLink);

});
// </nowiki>