Jump to content

User:Quarl/redirector.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.
// [[User:Quarl/redirector.js]] - "Redirector" application

// When you invoke the Redirector (through a tab), adds a new form to the
// document.  Start typing page names and press ENTER after each one.  A table
// will show the current status of each page (already a redirect, doesn't
// exist, etc.), and if you click "Redirect!", the target page will be updated
// to redirect to the current page.

// quarl 2006-02-09 initial version

// depends: util.js, wikipage.js, wikiedit.js, wikitabs.js

// <pre><nowiki>

var redirector = new Object();

// seconds between updates
redirector.update_interval = 1.0;

// maximum number of concurrent requests
redirector.max_concurrent_requests = 5;


redirector._entries = [];
redirector._requests_in_progress = 0;

redirector.run = function() {
    redirector.tab.innerHTML = '<a><b>Redirector</b></a>'; // prevent future clicks
    redirector.annotateDocument();
}

addStylesheetRule = function(tag, style) {
    var ss = document.styleSheets[0];
    if (ss.insertRule) {
        ss.insertRule(tag + '{' + style + '}', ss.cssRules.length);
    } else if (ss.addRule) {
        ss.addRule(tag, style);
    }
}

redirector.annotateDocument = function() {
    if (document.getElementById('redirector')) {
        // already done, called again for some reason
        return;
    }

    addStylesheetRule('#redirector', 'border: 1px solid red; padding: 1em;');
    addStylesheetRule('#redirector .redirectorStatus .downloading', 'color:grey');
    addStylesheetRule('#redirector .redirectorStatus .empty', 'color:black');
    addStylesheetRule('#redirector .redirectorStatus .toHere', 'color:green');
    addStylesheetRule('#redirector .redirectorStatus .toElsewhere', 'color:red');
    addStylesheetRule('#redirector .redirectorStatus .notRedirect', 'color:red');
    addStylesheetRule('#redirector .redirectorStatus .done', 'color:green');
    addStylesheetRule('#redirector .redirectorStatus .previous', 'text-decoration: line-through; color: #888;');

    var divLoc = document.getElementById('jump-to-nav');
    if (!divLoc) {
        alert("Redirector: couldn't get 'jump-to-nav' (error d5153643-a8c1-46ad-8d8e-c5d3fe066c77)");
        return null;
    }

    redirector.doc = new Object();
    redirector.doc.div = document.createElement('div');
    redirector.doc.div.id = 'redirector';

    redirector.doc.div.innerHTML = (
        '<h2>Redirector</h2>' +
        'Enter names of articles to redirect to <tt>'+wikiPage.page+'</tt>, and press ENTER after each one:' +
        '<form id="rcInputForm"><input type="text" id="rcConsole" name="rcConsole" size="60" value="'+wikiPage.page+'" />' +
        '<input type="submit" onclick="javascript:return redirector.inputClicked()" value="Enter" />' +
        '<input type="submit" onclick="javascript:return redirector.resetClicked()" value="Clear all" />' +
        '</form>' +
        '<table id="rcStatus" class="prettytable"><tr><th>Page</th><th>Status</th><th>Action</th></table>'
        );
    add_after(divLoc, redirector.doc.div);

    redirector.doc.rcConsole = document.getElementById('rcConsole');
    redirector.doc.rcStatus = document.getElementById('rcStatus');

    redirector.doc.rcConsole.focus();

    redirector._timerUpdate();
}

redirector.inputClicked = function() {
    var target = trimspaces(redirector.doc.rcConsole.value);
    if (!target) return false;
    if (target == wikiPage.page) return false;
    redirector.addEntry(target);
    // redirector.doc.rcConsole.value = wikiPage.page;
    return false;
}

redirector.resetClicked = function() {
    for (var i in redirector._entries) {
        redirector._entries[i].clearentry = true;
    }
    return false;
}

redirector.addEntry = function(s) {
    var t = new Object();

    // wiki page
    t.wp = new WikiPage(null, s);
    if (!t.wp) return;

    // delete old entry if any
    for (var i in redirector._entries) {
        if (redirector._entries[i].wp.page == t.wp.page) {
            redirector._entries[i].clearentry = true;
        }
    }

    // object for document status nodes.  null = not yet added
    t.statusnode = null;

    // download request status.  0 = not yet initiated; 1 = initiated; 2 =
    // finished
    t.downloadstatus = 0;

    // WikiEditor instance
    t.editor = null;

    // string value of old contents of target page
    t.oldcontents = null;
    t.oldredirect = null;

    // whether user has clicked "update" button
    t.updatewanted = false;

    // whether update requires confirmation
    t.updatedangerous = false;

    // update request status.  0 = not yet initiated; 1 = iniatited; 2 =
    // completed
    t.updatestatus = 0;

    // whether this entry should be cleared when done with it
    t.clearentry = false;
    t.ignore = false;

    redirector._entries.push(t);
    redirector.update();
}

// main action loop
redirector.update = function() {
    for (var i in redirector._entries) {
        var t = redirector._entries[i];

        if (t.ignore) continue;
        if (t.clearentry) {
            // only clear it if nothing in progress
            if ((t.downloadstatus == 0 || t.downloadstatus == 2) &&
                (t.updatestatus == 0 || t.updatestatus == 2))
            {
                t.statusnode.tr.parentNode.removeChild(t.statusnode.tr);
                t.ignore = true;
                continue;
            }
        }

        if (!t.statusnode) {
            redirector._addStatusNode(t);
        }

        if (redirector._requests_in_progress < redirector.max_concurrent_requests) {
            if (t.downloadstatus == 0) {
                redirector._initiateDownload(t);
            } else if (t.downloadstatus == 2 && t.updatewanted && t.updatestatus == 0) {
                redirector._initiateUpdate(t);
            }
        }
    }
}

redirector._timerUpdate = function() {
    redirector.update();
    setTimeout(redirector._timerUpdate, redirector.update_interval * 1000);
}

redirector._addStatusNode = function(t) {
    t.statusnode = new Object();
    t.statusnode.tr = document.createElement('tr');

    t.statusnode.page = document.createElement('td');
    var url = t.wp.qurl + '&redirect=no';
    var urlEdit = t.wp.qurl + '&action=edit';
    t.statusnode.page.innerHTML = (
        '<a href="' + url + '">' + t.wp.page + '</a>' +
        ' [<a href="' + urlEdit +'">edit</a>]');

    t.statusnode.status = document.createElement('td');
    t.statusnode.status.className = 'redirectorStatus';
    t.statusnode.status.innerHTML = '...';

    t.statusnode.action = document.createElement('td');
    t.statusnode.button = document.createElement('button');
    t.statusnode.button.onclick = function() { redirector._actionClick(t) };
    t.statusnode.button.disabled = true;
    t.statusnode.button.innerHTML = 'please wait';
    t.statusnode.action.appendChild(t.statusnode.button);

    t.statusnode.tr.appendChild(t.statusnode.page);
    t.statusnode.tr.appendChild(t.statusnode.status);
    t.statusnode.tr.appendChild(t.statusnode.action);

    redirector.doc.rcStatus.appendChild(t.statusnode.tr);
}

redirector._actionClick = function(t) {
    if (t.updatedangerous) {
        if (!window.confirm("The target is not a redirect.  Are you sure?")) return;
    }

    t.updatewanted = true;
    t.statusnode.button.disabled = true;
}

redirector._initiateDownload = function(t) {
    t.downloadstatus = 1;
    redirector._requests_in_progress ++;
    t.statusnode.status.innerHTML = '<span class="downloading">downloading...</span>';
    t.wp.getEditorAsync(redirector._downloadComplete, t);
}

redirector._downloadComplete = function(editor, t) {
    t.downloadstatus = 2;
    redirector._requests_in_progress --;
    t.editor = editor;
    t.oldcontents = t.editor.wpTextbox1;

    if (t.oldcontents.match(/^(?:\s|\n)*$/)) {
        t.status = 'empty';
        t.statustext = "empty";
        t.statusnode.button.innerHTML = 'Create redirect!';
        t.statusnode.button.disabled = false;
    } else if (t.oldcontents.match(/^\s*#REDIRECT \[\[(.+?)\]\]/i)) {
        t.oldredirect = RegExp.$1;
        t.oldredirectwp = new WikiPage(null, t.oldredirect);
        if (t.oldredirect == wikiPage.page) {
            t.status = 'toHere';
            t.statustext = 'redirect to here';
            t.statusnode.button.innerHTML = 'Nothing to do!';
            t.statusnode.button.disabled = true;
        } else {
            t.status = 'toElsewhere';
            t.statustext = 'redirect to <a href="'+t.oldredirectwp.url+'">'+t.oldredirectwp.page+'</a>';
            t.statusnode.button.innerHTML = 'Alter redirect!';
            t.updatedangerous = true;
            t.statusnode.button.disabled = false;
        }
    } else {
        t.status = 'notRedirect';
        t.old_wordcount = t.oldcontents.split(/\s+/).length;
        t.statustext = 'non-redirect (' + t.old_wordcount + ' words)';
        t.statusnode.button.innerHTML = 'Change to redirect';
        t.updatedangerous = true;
        t.statusnode.button.disabled = false;
    }

    t.statusnode.status.innerHTML = '<span class="'+t.status+'">' + t.statustext + '</span>';
}

redirector._initiateUpdate = function(t) {
    t.updatestatus = 1;
    t.statusnode.button.innerHTML = 'Submitting...';
    redirector._requests_in_progress ++;
    var rd = t.editor.wpTextbox1 = '#REDIRECT [[' + wikiPage.page + ']]\n';
    if (t.status == 'empty') {
        t.editor.wpSummary = 'Creating ' + rd;
    } else if (t.status == 'toElsewhere') {
        t.editor.wpSummary = 'Changing redirect from [[' + t.oldredirectwp.page + ']] to ' + rd;
    } else if (t.status == 'notRedirect') {
        t.editor.wpSummary = 'Changing article (' + t.old_wordcount + ' words) to ' + rd;
    } else {
        alert("internal error 3056fdaf-1147-4433-8334-d92eb2ffd8b7");
        return;
    }

    t.editor.submitAsync(null, redirector._updateComplete, t);
}

redirector._updateComplete = function(editor, t) {
    t.updatestatus = 2;
    t.statusnode.button.innerHTML = 'Done!';
    redirector._requests_in_progress --;

    t.statusnode.status.innerHTML = '<span class="done">Updated! (<span class="previous">' + t.statustext + '</span>)</span>';
}


redirector._load = function() {
    if (wikiPage.nsSpecialP) return;
    redirector.tab = wikitabs.addToolboxLink('javascript:redirector.run()', 'Redirector', 'ca-redirector');
}

addOnloadHook(redirector._load);

// </nowiki></pre>