User:Pathoschild/monobook.js

From Wikipedia, the free encyclopedia

Note: After saving, you have to bypass your browser's cache to see the changes. Firefox/Mozilla/Safari: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Internet Explorer: press Ctrl-F5, Opera/Konqueror: press F5.

If a message on your talk page led you here, please be wary of who left it. The code below could contain malicious content capable of compromising your account; if your account appears to be compromised, it will be blocked. If you are unsure of whether the code is safe, you can ask at the help desk.
// <pre>
/*
#########
### Data functions
###  provide generic data for other scripts
#########
*/
	/*
	#########
	### getElementsByClassName [2005/07/14]
	###  by Jonathan Snook (http://www.snook.ca/jonathan) with addons by Robert Nyman (http://www.robertnyman.com)
	###    * adds a function which gets an object given its class
	###    * documentation: http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
	#########
	*/
	function getElementsByClassName(oElm, strTagName, strClassName){
		var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
		var arrReturnElements = new Array();
		strClassName = strClassName.replace(/\-/g, "\\-");
		var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
		var oElement;
		for(var i=0; i<arrElements.length; i++){
			oElement = arrElements[i];      
			if(oRegExp.test(oElement.className)){
				arrReturnElements.push(oElement);
			}
		}
		return (arrReturnElements)
	}

	/*
	#########
	### GetElement function [dev]
	###  by [[user:Pathoschild]]
	###    * function which retrieves a given element on the current page
	#########
	*/
	
	function fGetElement(uElement) {
		var strSkin = skin;
	
		/* particular skins */
		if(skin == 'monobook') {
			switch(uElement) {
				case 'sitenotice': return document.getElementById('siteNotice'); break
			}
		}
		else {
			scriptReturn('fGetElement','The current skin is not supported.','error_support');
		}
		
		/* all skins */
		switch(uElement) {
			case 'head': return document.getElementsByTagName('head')[0]; break
		}
	}

	/*
	#########
	### PageData function [dev]
	###  by [[user:Pathoschild]]
	###    * adds a function which retrieves data on the current page
	#########
	*/


	/* function */
	function fPageData(uQuery) {
		// URL
		var regUrlSimple = /.*\/wiki\/.*/;
		var regUrlComplex = /.*\?title=.*/;
		var regdomain = /^(?:http:\/\/)?(?:www.)?([^\/]*).*/;
		var strFullUrl = location.href;
		var strDomain = strFullUrl.replace(regdomain,'$1');
		
		// URL type
		if(uQuery == 'urltype') {
			if(strFullUrl.match(regUrlComplex)) {
				var strUrlType = 'complex';
			}
			else if(strFullUrl.match(regUrlSimple)) {
				var strUrlType = 'simple';
			}
			else {
				var strUrlType = 'nonstandard';
			}
		}
	
		// pagename
		var regNamespace = /^([^:]*).*/ // very flawed, should replace with number returned by document.body.getAttribute('class') when that works.
		var regFullPagename = /.*(?:title=|\/wiki\/)([^&#]+).*/;
		var regNamespace = /ns-([0-9])/;
		
		var strFullPagename = strFullUrl.replace(regFullPagename,'$1'); // very flawed (see regNamespace)
		var strNamespace = strFullPagename.replace(regNamespace,'$1');
		var strPagename = strFullPagename.replace(regNamespace,''); // very flawed (see regNamespace)
		var arrPageTree = strFullPagename.split('/');
	
		// current view
		if(uQuery == 'currentform' || uQuery == 'currentforminput' || uQuery == 'currentview') {
			// form types
			var regFormEdit = /&action=(?:edit|submit)/;
			var regFormMove = /Special:Movepage/;
			var regFormDelete = /&action=delete/;
			var regFormUndelete = /Special:Undelete/;
			var regFormProtect = /&action=protect/;
			var regFormBlock = /Special:Blockip/;
			var regFormUnblock = /&action=unblock/;
	
			// input boxes
			var objInputEdit = document.getElementById('wpTextbox1');
			var objInputMove = document.getElementById('wpReason'); // caution! same id as delete
			var objInputDelete = document.getElementById('wpReason'); // caution! same id as move
			var objInputUndelete = document.getElementsByName('wpComment')[0]; // name (no id)
			var objInputProtect = document.getElementById('mwProtect-reason');
			var objInputBlock = document.getElementsByName('wpBlockReason')[0]; // name (no id)
			var objInputUnblock = document.getElementsByName('wpUnblockReason')[0]; // name (no id)
			
			// set values
			if(strFullUrl.match(regFormEdit)) {
				var strCurrentForm = 'edit';
				var strCurrentView = strCurrentForm;
				var objCurrentFormInput = objInputEdit;
			}
			else if(strFullUrl.match(regFormMove)) {
				var strCurrentForm = 'move';
				var strCurrentView = strCurrentForm;
				var objCurrentFormInput = objInputMove;
			}
			else if(strFullUrl.match(regFormDelete)) {
				var strCurrentForm = 'delete';
				var strCurrentView = strCurrentForm;
				var objCurrentFormInput = objInputDelete;
			}
			else if(strFullUrl.match(regFormUndelete)) {
				var strCurrentForm = 'undelete';
				var strCurrentView = strCurrentForm;
				var objCurrentFormInput = objInputUndelete;
			}
			else if(strFullUrl.match(regFormProtect)) {
				var strCurrentForm = 'protect';
				var strCurrentView = strCurrentForm;
				var objCurrentFormInput = objInputProtect;
			}
			else if(strFullUrl.match(regFormBlock)) {
				var strCurrentForm = 'block';
				var strCurrentView = strCurrentForm;
				var objCurrentFormInput = objInputBlock;
			}
			else if(strFullUrl.match(regFormUnblock)) {
				var strCurrentForm = 'unblock';
				var strCurrentView = strCurrentForm;
				var objCurrentFormInput = objInputUnblock;
			}
			else {
				var strCurrentForm = false;
				var objCurrentFormInput = false;
				
				// non-Forms
				var regHistory = /action=history/;
				
				if(strFullUrl.match(regHistory)) {
					var strCurrentView = 'history';
				}
				else {
					var strCurrentView = false;
				}
			}
		}
	
		/* return data */
		switch(uQuery) {
			// URL
			case 'url': return strFullUrl; break
			case 'domain': return strDomain; break
			case 'urltype': return strUrlType; break
			
			// pagename
			case 'fullpagename': return strFullPagename; break
			case 'pagename': return strPagename; break
			case 'namespace': return strNamespace; break
			case 'pagetree': return arrPageTree; break
			
			// view
			case 'currentview': return strCurrentView; break
			case 'currentform': return strCurrentForm; break
			case 'currentforminput': return objCurrentFormInput; break
		}
	}

/*
#########
### Misc functions
###  accomplish generic tasks for other scripts
#########
*/
	/*
	#########
	### ScriptReturn[1.0]
	###  by [[user:Pathoschild]]
	###    * function which allows scripts to output to a single table above the page header
	#########
	*/
	function scriptReturn(scriptname,returntext,utype) {
		/* create table if it doesn't exist yet */
		if(!document.getElementById('scriptReturn')) {
			/* table  */	
			var objTable = document.createElement('table');
			objTable.setAttribute('class','prettytable');
			objTable.setAttribute('id','scriptReturn');
			objTable.setAttribute('style','text-align:left;');
			
			/* header */
			var objHeader = document.createElement('tr');
			var objHeaderC1 = document.createElement('th');
			var objHeaderC2 = document.createElement('th');
			var objHeaderC1Text = document.createTextNode('Script');
			var objHeaderC2Text = document.createTextNode('Return');
			objHeaderC1.appendChild(objHeaderC1Text);
			objHeaderC2.appendChild(objHeaderC2Text);
			objHeader.appendChild(objHeaderC1);
			objHeader.appendChild(objHeaderC2);
			objTable.appendChild(objHeader);
		}
		else {
			var objTable = document.getElementById('scriptReturn');
		}
		
		/* row */
		var objRow = document.createElement('tr');
		var objRowC1 = document.createElement('td');
		var objRowC2 = document.createElement('td');
		var objRowC1Text = document.createTextNode(scriptname);
		var objRowC2Text = document.createTextNode(returntext);
	
		/* type icon */
		if(utype) {
			/* define url */
			switch(utype) {
			case 'info': var strIconUrl = 'http://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Crystal_Clear_Ktip.png/20px-Crystal_Clear_Ktip.png'; break
			case 'error_misc': var strIconUrl = 'http://upload.wikimedia.org/wikipedia/commons/2/2e/Crystal_Clear_action_button_cancel.png'; break
			case 'error_req': var strIconUrl = 'http://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Crystal_Clear_action_button_cancel.png/20px-Crystal_Clear_action_button_cancel.png'; break
			case 'error_support': var strIconUrl = 'http://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/Crystal_Clear_action_editdelete.png/20px-Crystal_Clear_action_editdelete.png'; break
			}
		}
		else {
			strIconUrl = 'http://upload.wikimedia.org/wikipedia/commons/e/ec/Blank_50px.png';
		}
	
		var objIcon = document.createElement('img');
		objIcon.setAttribute('src',strIconUrl);
		objIcon.setAttribute('alt','['+utype+']');
		/* objIcon.setAttribute('style','margin-right:3px;'); */
	
		/* output  */
		var objSiteNotice = document.getElementById('siteNotice');
		objRowC1.appendChild(objRowC1Text);
		objRowC2.appendChild(objIcon);
		objRowC2.appendChild(objRowC2Text);
		objRow.appendChild(objRowC1);
		objRow.appendChild(objRowC2);
		objTable.appendChild(objRow);
	
		objSiteNotice.appendChild(objTable);
	}

/* 
#########
### formDefaults[dev]
###  by Pathoschild
###    * automatically inserts  default form values.
#########
*/

function formDefaults() {
	if(fPageData('currentform') == 'delete') {
		var objReason = fPageData('currentforminput');
		objReason.value = '[[WP:DENY|Unneeded userpage for an indefinitely blocked user]]';
		var watchbox = document.getElementById('wpWatch');
		watchbox.checked = true;
	}
	else if(fPageData('currentform') == 'unblock') {
		var objReason = fPageData('currentforminput');
		objReason.value = 'Override [[Wikipedia:Autoblock|autoblock]]';
	}
}

addOnloadHook(function() {formDefaults()});

/*
#########
### TemplateScript
###  by [[user:Pathoschild]]
###    * adds a menu of user-defined, form-specific templates
###    * documentation: [http://en.wikisource.org/wiki/user:pathoschild/About/TemplateScript]
#########
*/

document.write('<script type="text/javascript" src="'
  + 'http://meta.wikimedia.org/w/index.php?title=User:Pathoschild/Script:TemplateScript.js' 
  + '&action=raw&ctype=text/javascript&dontcountme=s"></script>');

/* define templates */
function define_templates() {
	/* syntax: new_template('type','name','text','optional 1','optional 2','optional 3');
	     see documentation
	*/
	new_template('edit','RFI notification','== Request for investigation processed ==\n{{subst:User:Pathoschild/Form/RFI notification\n |reporter = {{subst:PAGENAME}}\n |reportee =\n |current  = reportee\n |action   =\n |comment  =\n}} // ~~~','+ "Request for investigation processed"');
	new_template('edit','rd to talk','#redirect [[user talk:{{subst:PAGENAME}}]]');
	new_template('edit','process header','{{process header\n | title    =\n | section  =\n | previous =\n | next     =\n | shortcut =\n | notes    =\n}}');
	new_template('edit','Protected deletion','{{deletedpage-r\n |reason = [[WP:CSD|Criteria for speedy deletion]] G4 (recreation of deleted content)\n |admin  =\n}}');
	new_template('edit','{{s/block}}','{{subst:s/block\n |time      = 1 hour\n |reason    = for [[WP:VAND|Vandalism]]\n |signature = // ~~~~}}');
	new_template('edit','deprecated t','{{tdeprecated|{{subst:lc:{{subst:PAGENAME}}}}|new|date=October 2006}}','{{deprecated template}}');
	new_template('edit','RFI DR','==Your request for investigation==\nHello {{subst:PAGENAME}}. Please attempt the [[WP:DR|dispute resolution process]] before filing a [[WP:RFI|request for investigation or watchlisting]] into [[User:~|]]. If you have followed the process, please provide links showing this in your next request. Thanks. ~~~','+ Your request for investigation');
	new_template('edit','OTRS rm unsourced','==Cite reliable sources==\nI have removed a large amount of unreferenced information from this article following a complaint (<small>{{OTRS ticket|502785|2006110810008642}}</small>). Please cite reliable sources for all information in this and any other article in accordance with the [[WP:V|Verifiability policy]] and [[WP:RS|Reliable sources guidelines]]. If possible, please use the [[Wikipedia:Footnotes|footnote syntax]] to clearly designate which source supports a particular piece of information. ~~~','+ "Cite reliable sources"');

	new_template('block','U confusing/symbols/spam','[[WP:U|Username policy]] violation (one of the following): misleading, confusing, or random; disallowed characters; web domain or email address','indefinite',false);
	new_template('block','U reference','[[WP:U|Username policy]] violation (one of the following): imitation of an IP address or username; reference to an existing user or organisation');
	new_template('block','U message','[[WP:U|Username policy]] violation (one of the following): political, religious, or other statement; message or comment which does not serve as a suitable username','indefinite',false);
	new_template('block','U verify','This username matches a recent pattern of malicious or suspicious usernames. For verification purposes, please [[m:H:EC|confirm an email address]] and [[Special:Emailuser/Pathoschild|email me]], or follow the instructions on this page.','indefinite',false);
	new_template('block','edit verify','This account\'s editing pattern matches those of recent malicious or suspicious accounts. For verification purposes, please [[Help:Email confirmation|confirm an email address]] and [[Special:Emailuser/Pathoschild|email me]], or follow the instructions on this page.','indefinite',true);
	new_template('block','vandalism','[[WP:VAND|Vandalism]]','indefinite',true);
	new_template('block','open/zombie','[[Open proxy]] or [[Zombie computer|zombie]] (see [[WP:OP|WikiProject on open proxies]] for information)','indefinite',true);
	new_template('block','sleeper','This account has been blocked as a possible malicious sleeper account. If it was created in good faith, please [[m:H:EC|confirm an email address]] and [[Special:Emailuser/Pathoschild|email me]].','indefinite',true);

	new_template('delete','DenyRecognition','[[WP:DENY|Userpage for an indefinitely blocked bad-faith user]]');
	new_template('delete','email block','Tagging email username blocks exposes the email address (not necessarily owned by the username creator) to spam harvesting and misleading search engine results.');
	new_template('delete','redundant with talk','redundant with talk page');

	new_template('unblock','rm autoblock','Override [[Wikipedia:Autoblock|autoblock]]');
}

/* Load script */
addOnloadHook(function() {templatescript(define_templates(),'1.5')});


/*
#########
### TranswikiLog [dev]
###  by [[user:Pathoschild]]
###    * generates a wikiML log from the history or undelete view of a oage for pasting alongside a transwiki.
###    * about transwiki: [http://meta.wikimedia.org/wiki/transwiki]
#########
*/
var strInterwiki = 'w:';
var strProject = 'Wikipedia';

function transwikiLog() {
	/* function: wikify data */
	function fWikify(uObject,type) {
		if(!uObject) {
			return '';
		}
		else {
			var objInput = uObject;
			if(type == 'summary') {
				// remove surrounding brackets
				objInput = objInput.replace(/^\(|\)$/g,'');
				// convert links
				objInput = objInput.replace(/<a[^\>]*title="([^>]*)">([^\<]*)<\/a>/ig,'[['+strInterwiki+'$1|$2]]');
				// escape templates
				objInput = objInput.replace(/({{[^\}]*}})/g,'<nowiki>$1</nowiki>');
			
				return objInput;
			}
			else if(type == 'username') {
				// link username
				objInput = objInput.replace(/^(?:user:)?(.*)$/ig,'[['+strInterwiki+'User:$1|$1]]');
				return objInput;
			}
			else if(type == 'page') {
				// link page
				objInput = objInput.replace(/^(.*)$/g,'[['+strInterwiki+'$1|$1]]');
				return objInput;
			}
			else {
				return '';
			}
		}
	}

	/* overall variables */
	var strView = fPageData('currentview');
	var strForm = fPageData('currentform');
	
	var objSitenotice = fGetElement('sitenotice');

	/* if on a supported form... */
	if(strView == 'history' || strForm == 'undelete') {
		/* determine log type */
		if(strView == 'history') {
			scriptReturn('transwikiLog','This view should be supported... but isn\'t. This *is* a pre-release script, after all.','error_support');
		}
		else {
			/* search for headers */
			var objarrHeaders = document.getElementsByTagName('h2');
			for(i=0; i<objarrHeaders.length; i++) {
				/* note which header is each relevant log (on the assumption the corresponding nth table is that log) */
				if(objarrHeaders[i].firstChild.nodeValue.match(/deletion/i)) {
					var intHeaderDelete = i;
				}
				else if(objarrHeaders[i].firstChild.nodeValue.match(/page history/i)) {
					var intHeaderEdit = i;
				}
			}
			
			/* get logs */
			var arrTables = document.getElementsByTagName('ul');
			
			/* parse deletion log */
			if(intHeaderDelete || intHeaderDelete === 0) {		
				/* retrieve log rows and define arrays */
				var objarrDeleteRows = arrTables[intHeaderDelete].getElementsByTagName('li');
				arrDeleteDate = new Array();
				arrDeleteUser = new Array();
				arrDeleteAction = new Array();
				arrDeletePage = new Array();
				arrDeleteReason = new Array();
				
				/* error-check */
				if(!objarrDeleteRows) {
					scriptReturn('transwikiLog','Error: unable to parse deletion log. Please report this problem to [http://meta.wikimedia.org/user_talk:pathoschild].','error_misc')
				}
				else {
					/* parse each row */
					for(i=0; i<objarrDeleteRows.length; i++) {
						/* retrieve data from DOM */
						arrDeleteDate[i] = objarrDeleteRows[i].firstChild.nodeValue;
						arrDeleteUser[i] = objarrDeleteRows[i].getElementsByTagName('a')[0].title;
						arrDeleteAction[i] = objarrDeleteRows[i].innerHTML.replace(/^.*(restored|deleted) "<a[^\>]*>[^\<]+.*$/,'$1');
						arrDeletePage[i] = objarrDeleteRows[i].innerHTML.replace(/^.*(?:restored|deleted) "<a[^\>]*>([^\<]+).*$/,'$1');
						if(objarrDeleteRows[i].getElementsByTagName('span')[0]) {
							arrDeleteReason[i] = objarrDeleteRows[i].getElementsByTagName('span')[0].innerHTML;
						}
						else {
							arrDeleteReason[i] = '';
						}
					}
				}
			}
			/* parse edit log */
			if(intHeaderEdit || intHeaderEdit === 0) {		
				/* retrieve log rows and define arrays */
				var objarrEditRows = arrTables[intHeaderEdit].getElementsByTagName('li');
				arrEditDate = new Array();
				arrEditUser = new Array();
				arrEditSummary = new Array();
				
				/* error-check */
				if(!objarrEditRows) {
					scriptReturn('transwikiLog','Error: unable to parse edit log. Please report this problem to [http://meta.wikimedia.org/user_talk:pathoschild].','error_misc')
				}
				else {
					/* parse each row */
					for(i=0; i<objarrEditRows.length; i++) {
						/* retrieve data from DOM */
						arrEditDate[i] = objarrEditRows[i].getElementsByTagName('a')[0].firstChild.nodeValue;
						// IP addresses
						if(objarrEditRows[i].getElementsByTagName('a')[1].title.match(/Special:Contributions/i)) {
							arrEditUser[i] = objarrEditRows[i].getElementsByTagName('a')[1].href.replace(/^.*target=([0-9\.]+).*$/,'$1');
						}
						// Registered users
						else {
							arrEditUser[i] = objarrEditRows[i].getElementsByTagName('a')[1].title;
						}
						// Skip if no edit summary
						if(objarrEditRows[i].getElementsByTagName('span')[0]) {
							arrEditSummary[i] = objarrEditRows[i].getElementsByTagName('span')[0].innerHTML;
						}
					}
				}
			}

			/* build output */
			if(arrDeletePage[0]) {
				strOldPage = arrDeletePage[0];
			}
			else {
				strOldPage = '{{subst:PAGENAME}}';
			}
			
			var strOutput = '{{transwiki\n |oldlocation = "[[w:'+strOldPage+'|'+strOldPage+']]" on [[w:|Wikipedia]]\n |log         = yes\n}}\n\n== History ==\n';
			
			/* generate deletion log */
			if(objarrDeleteRows) {
				strOutput += '=== Deletion log ===\n{| class="prettytable"\n|-\n! timestamp !! admin !! action !! reason\n';
				for(i=0;i<objarrDeleteRows.length;i++) {
					/* wikify */
					arrDeleteUser[i] = fWikify(arrDeleteUser[i],'username');
					arrDeletePage[i] = fWikify(arrDeletePage[i],'page');
					arrDeleteReason[i] = fWikify(arrDeleteReason[i],'summary');
					
					/* output */
					strOutput += '|-\n| '+arrDeleteDate[i]+'\n| '+arrDeleteUser[i]+'\n| '+arrDeleteAction[i]+' "'+arrDeletePage[i]+'"\n| '+arrDeleteReason[i]+'\n';
				}
				strOutput +='|}\n\n';
			}
			
			/* generate edit log */
			if(objarrEditRows) {
				strOutput += '=== Edit log ===\n{| class="prettytable"\n|-\n! timestamp !! user !! edit summary\n';
				for(i=0;i<objarrEditRows.length;i++) {
					/* wikify */
					arrEditUser[i] = fWikify(arrEditUser[i],'username');
					arrEditSummary[i] = fWikify(arrEditSummary[i],'summary');
									
					/* output */
					strOutput += '|-\n| '+arrEditDate[i]+'\n| '+arrEditUser[i]+'\n| '+arrEditSummary[i]+'\n';
				}
				strOutput +='|}\n\n';
			}
			
			/* output output */
			var objSitenotice = document.getElementById('siteNotice');
			var objTextarea = document.createElement('textarea');
			var objOutput = document.createTextNode(strOutput);
			objTextarea.setAttribute('style','width:100%; height:350px;');
			objTextarea.appendChild(objOutput);
			objSitenotice.appendChild(objTextarea);
		}
	}
}


/* load script */
 addOnloadHook(function() {transwikiLog()});