User:Xover/Gadget-sandbox.js

From Wikisource
Jump to navigation Jump to search
Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Clear the cache in Tools → Preferences

For details and instructions about other browsers, see Wikipedia:Bypass your cache.

mw.loader.using(['mediawiki.api', 'mediawiki.Title'], function () {
    "use strict";

    var config = mw.config.get(['wgNamespaceNumber', 'wgTitle', 'wgUserGroups', 'wgUserName']);

    function doMassDelete() {
        $("#wpMassDeleteSubmit").prop("disabled", true);
        var pages = $("#wpMassDeletePages").val().split("\n").filter(function (l) {
        	return l.trim(); // Empty strings are false so .filter drops them.
        });
        if (!pages.length) {
            return;
        }

        var wpMassDeleteReasons = $("#wpMassDeleteReasons option:selected").text(); console.log("wpMassDeleteReasons = " + wpMassDeleteReasons);
        var wpMassDeleteReason = $("#wpMassDeleteReason").val(); console.log("wpMassDeleteReason = " + wpMassDeleteReason);
        var action = "delete";
        if ($("input[name='action']:checked").val() === "undelete") {
        	action = "undelete";
        }
        console.log("action = " + action);

        var api = new mw.Api();
        var deleted = 0;
        var failed = [];
        var error = [];
        var deferreds = [];
		var reason = "";
        if (wpMassDeleteReasons === "other") {
        	reason = wpMassDeleteReason; // Just the text field, even if empty.
        } else {
        	reason = wpMassDeleteReasons; // Just the menu selection.
        	if (wpMassDeleteReason !== "") {
        		// Add on the text field if it contains any text.
        		reason = reason + " (" + wpMassDeleteReason + ")";
        	}
        }
        console.log("Using reason: " + reason);
        var onSuccess = function () {
            deleted++;
            $("#wpMassDeleteSubmit").val("(" + deleted + "/" + pages.length + ")");
        };

        function makeDeleteFunc(article, action) {
            return function () {
                return $.Deferred(function (deferred) {
                	console.log("Will act on: " + article);
                    var promise = api.postWithToken('csrf', {
                        format: 'json',
                        action: action,
                        title: article,
                        reason: reason
                    });
                    promise.done(onSuccess);
                    promise.fail(function (code, obj) {
                        failed.push(article);
                        error.push(obj.error.info);
                    });
                    promise.always(function () {
                        deferred.resolve();
                    });
                });
            };
        }


		function setFlood(floodState) {
			var reason = (floodState ? "+" : "-") + "flood for bulk action";
			var params = {
				action: 'userrights',
				user: config.wgUserName,
				reason: reason,
				format: 'json'
			};
			if (floodState === true) {
				params.add = "flood";
			} else {
				params.remove = "flood";
			}
			var api = new mw.Api();
			api.postWithToken('userrights', params);
		}

        // Make a chain of deferred objects. We chain them rather than execute
        // them in parallel so that we don't make 1000 simultaneous delete
        // requests and bring the site down. We use deferred objects rather than
        // the promise objects returned from the API request so that the chain
        // continues even if some pages gave errors.
        setFlood(true); console.log("Turning flood flag on…");
        var deferred = makeDeleteFunc(pages[0], action)();
        for (var i = 1, len = pages.length; i < len; i++) {
            deferred = deferred.then(makeDeleteFunc(pages[i], action));
        }

        // Show the output and do cleanup once all the requests are done.
        $.when(deferred).then(function () {
            $("#wpMassDeleteSubmit").val("Done (" + deleted + "/" + pages.length + ")");
            if (failed.length) {
                var $failedList = $('<ul>');
                for (var x = 0; x < failed.length; x++) {
                    // Link the titles in the "failed" array
                    var failedTitle = mw.Title.newFromText(failed[x]);
                    var $failedItem = $('<li>');
                    if (failedTitle) {
                        $failedItem.append(
                        	$('<a>').attr('href', failedTitle.getUrl())
                            	.text(failed[x])
                        );
                    } else {
                        $failedItem.text(failed[x]);
                    }
                    $failedItem.append(document.createTextNode(': ' + error[x]));
                    $failedList.append($failedItem);
                }
                $('#wpMassDeleteFailedContainer')
                    .append('<br />')
                    .append($('<span style="font-weight: bold">').text('Failed deletions:'))
                    .append($failedList);
            }
            setFlood(false); console.log("Turning flood flag off…");
        });
    }
     
    function massdeleteform() {
        $("h1").text("Mass delete pages");
        document.title = "Mass delete pages";
        $('#bodyContent').html(
        '<div>' +
            '<form id="wpMassDelete" name="wpMassDelete">' +
            '<p>If you are deleting multiple pages that were created by one user, please use <a href="/wiki/Special:Nuke">Special:Nuke</a>!</p>' +
            '<p>Add the list of pages to delete in the text box below, one page per line.</p>' +
            '<div id="wpMassDeleteFailedContainer"></div>' +
            '<br />' +
                'Pages to delete (one on each line, please):<br />' +
                '<textarea tabindex="1" accesskey="," name="wpMassDeletePages" id="wpMassDeletePages" rows="15" cols="80"></textarea>' +
                '<input type="radio" id="delete" name="action" value="delete" checked> <label for="delete">Delete</label><br />' +
                '<input type="radio" id="undelete" name="action" value="undelete"> <label for="undelete">Undelete</label><br />' +
                '<table>' +
                    '<tr><td>Common reasons:</td>' +
                        '<td><select id="wpMassDeleteReasons">' +
                            '<optgroup label="Other reason">' +
                                '<option value="other">Other reason</option>' +
                            '</optgroup>' +
                            '<optgroup label="Criteria for speedy deletion">' +
                                '<optgroup label="General">' +
                                    '<option value="G1">G1: No meaningful content or history</option>' +
                                    '<option value="G2">G2: Reposted content</option>' +
                                    '<option value="G3">G3: Banned contributor</option>' +
                                    '<option value="G4">G4: Redundant</option>' +
                                    '<option value="G5">G5: Beyond scope</option>' +
                                    '<option value="G6">G6: Copyright violation</option>' +
                                    '<option value="G7">G7: Author’s request</option>' +
                                    '<option value="G8">G8: Person-based categories</option>' +
                                '</optgroup>' +
                                '<optgroup label="Articles and images">' +
                                    '<option value="A1">A1: Articles transwikied to another project</option>' +
                                    '<option value="A2">A2: Non-notable content</option>' +
                                    '<option value="A3">A3: Works without authorship information</option>' +
                                '</optgroup>' +
                                '<optgroup label="Miscellaneous">' +
                                    '<option value="M1">M1: Process deletion</option>' +
                                    '<option value="M2">M2: Unneeded redirects</option>' +
                                    '<option value="M3">M3: Cross-namespace redirects</option>' +
                                    '<option value="M4">M4: Orphaned talk page</option>' +
                                '</optgroup>' +
                            '</optgroup>' +
                            '<optgroup label="Community consensus">' +
                                '<option value="PD">Proposed deletion</option>' +
                                '<option value="CV">Copyright discussion</option>' +
                            '</optgroup>' +
                        '</select></td></tr>' +
                    '<tr><td>Other or additional reason:</td>' +
                    '<td><input type="text" id="wpMassDeleteReason" name="wpMassDeleteReason" size="80" maxlength="1000" /></td></tr>' +
                    '<tr><td><input type="button" id="wpMassDeleteSubmit" name="wpMassDeleteSubmit" value="Delete" /></td>' +
            '</form>' +
        '</div>'
        );
        $("#wpMassDeleteReasons").on("change", function () {
            var maxlength = 1000;
            if ($("#wpMassDeleteReasons").val() === "other") {
            	// Use the full length for the custom reason in the text field.
            	maxlength = maxlength;
            } else {
            	// Reserve room for the space and parenthesis we will add.
            	maxlength = maxlength - 3;
            	// Then deduct the length of the prebaked option from the menu.
            	maxlength = maxlength - $("#wpMassDeleteReasons").val().length;
            }
            $("#wpMassDeleteReason").prop("maxlength", maxlength);
        });
        $("#wpMassDeleteSubmit").on("click", function (e) {
            doMassDelete();
        });
        $('[name="action"]').on('change', function() {
		    if ($(this).attr('id') == 'undelete') {
        		$('#wpMassDeleteSubmit').prop('value', 'Undelete');
		    } else {
        		$('#wpMassDeleteSubmit').prop('value', 'Delete');
    		}
		});
    }
     
    if (config.wgNamespaceNumber == -1 &&
        config.wgTitle.toLowerCase() == "massdelete" &&
        /sysop/.test(config.wgUserGroups)
    ) {
        massdeleteform();
    }

});