User:Quarl/redirector.js

// 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

//

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 = 'Redirector'; // 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 = (

'

Redirector

' +

'Enter names of articles to redirect to '+wikiPage.page+', and press ENTER after each one:' +

'

' +

'' +

'' +

'

' +

'

PageStatusAction
'

);

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 = (

'' + t.wp.page + '' +

' [edit]');

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 = 'downloading...';

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 '+t.oldredirectwp.page+'';

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 = '' + t.statustext + '';

}

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 = 'Updated! (' + t.statustext + ')';

}

redirector._load = function() {

if (wikiPage.nsSpecialP) return;

redirector.tab = wikitabs.addToolboxLink('javascript:redirector.run()', 'Redirector', 'ca-redirector');

}

addOnloadHook(redirector._load);

//