User:Mike.lifeguard/regexliFilter.js

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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// <source lang="javascript">
// Log filter script
// Created by [[w:User:Splarka|Splarka]] & amended [[b:User:Mike.lifeguard]] & [[User:Lupo]]
/* <li> element Filter Script, version [0.1.1]
Should currently work on all known skins (with a #contentSub or #topbar)
*/
var rightsLogOnly = !(document.location.href.indexOf('type=rights') == -1 && document.location.href.indexOf('Log/rights') == -1);
if (mw.config.get('wgAction') == 'history' || mw.config.get('wgCanonicalSpecialPageName') == 'Search' || mw.config.get('wgCanonicalSpecialPageName') == 'Log' || mw.config.get('wgCanonicalSpecialPageName') == 'CheckUser' || mw.config.get('wgCanonicalSpecialPageName') == 'LinkSearch' || mw.config.get('wgCanonicalSpecialPageName') == 'Contributions' || mw.config.get('wgCanonicalSpecialPageName') == 'IPBlockList' || queryString('lifilter'))
	$(filterLiButton);

function filterLiButton() {
	if (document.getElementById('p-cactions')) {
		mw.util.addPortletLink('p-cactions', 'javascript:filterLiForm()', 'Filter', 'ca-rxfilter', 'Open interactive log entry regex filter thingy');
		if (window.AutoLoadLogsFilter || queryString('lifilter')) filterLiForm();
	}
	else
		filterLiForm(); //not a portlet skin, so add the filter anyway.
}

function filterLiForm() {
	var instructions = (rightsLogOnly) ? 'Regex filter the space-delimited list of rights.' : 'Regex filter the plain text representation of this list.';
		//generate the form
	try {
		document.getElementById('ca-rxfilter').style.display = 'none';
	}
	catch (e) {}
	var obj = (document.getElementById('contentSub')) ? document.getElementById('contentSub') : document.getElementById('topbar');
	if (!obj)
		return;
	var rf = document.createElement('div');
	rf.setAttribute('id', 'rfform');
	rf.style.color = 'black';
	var fs = document.createElement('fieldset');
	var is = document.createElement('p');
	is.appendChild(document.createTextNode(instructions));
	fs.appendChild(is);
	var lg = document.createElement('legend');
	lg.appendChild(document.createTextNode('Filter <li> list (javascript)'));
	fs.appendChild(lg);
	if (rightsLogOnly) {
		var sel = document.createElement('select');
		sel.setAttribute('id', 'rfselect');
		var op1 = document.createElement('option');
		op1.appendChild(document.createTextNode('added rights'));
		sel.appendChild(op1);
		var op2 = document.createElement('option');
		op2.appendChild(document.createTextNode('removed rights'));
		sel.appendChild(op2);
		var op3 = document.createElement('option');
		op3.appendChild(document.createTextNode('added OR removed'));
		sel.appendChild(op3);
		var op4 = document.createElement('option');
		op4.appendChild(document.createTextNode('added/removed/static'));
		sel.appendChild(op4);
		fs.appendChild(sel);
	}
	var lab1 = document.createElement('label');
	lab1.appendChild(document.createTextNode(' Regex string: '));
	lab1.setAttribute('for', 'rfinput1');
	fs.appendChild(lab1);
	fs.appendChild(document.createTextNode(' '));
	var inp1 = document.createElement('input');
	inp1.setAttribute('id', 'rfinput1');
	inp1.setAttribute('name', 'rfinput1');
	inp1.setAttribute('type', 'text');
	fs.appendChild(inp1);
	var chk1 = document.createElement('input');
	chk1.setAttribute('id', 'rfinput2');
	chk1.setAttribute('name', 'rfinput2');
	chk1.setAttribute('type', 'checkbox');
	fs.appendChild(chk1);
	var lab2 = document.createElement('label');
	lab2.appendChild(document.createTextNode('Invert '));
	lab2.setAttribute('for', 'rfinput2');
	fs.appendChild(lab2);

	var chk2 = document.createElement('input');
	chk2.setAttribute('id', 'rfinput_case');
	chk2.setAttribute('name', 'rfinput_case');
	chk2.setAttribute('type', 'checkbox');
	chk2.checked = true; // Default: case-insensitive.
	fs.appendChild(chk2);
	lab2 = document.createElement('label');
	lab2.appendChild(document.createTextNode('Case insensitive '));
	lab2.setAttribute('for', 'rfinput_case');
	fs.appendChild(lab2);

	var sub1 = document.createElement('input');
	sub1.setAttribute('type', 'button');
	sub1.setAttribute('value', 'filter');
	$(sub1).click(function() {
		filterLi(false);
	});
	sub1.setAttribute('onclick', '');
	fs.appendChild(sub1)
	fs.appendChild(document.createTextNode(' '));
	var sub2 = document.createElement('input');
	sub2.setAttribute('type', 'button');
	sub2.setAttribute('value', 'hilight');
	sub2.click(function() {
		filterLi(true);
	});
	fs.appendChild(sub2);
	rf.appendChild(fs);
	obj.appendChild(rf);
}

function filterLi(hilight) {
	//grab options from form
	if (rightsLogOnly)
		var type = document.getElementById('rfselect').selectedIndex;
	var invert = document.getElementById('rfinput2').checked;
	var srch = document.getElementById('rfinput1').value;
	var flags = (document.getElementById('rfinput_case').checked ? 'ig' : 'g');
	var rx = new RegExp(srch, flags);

	//grab the list of all <li> in the content
	var bod = (document.getElementById('bodyContent')) ? document.getElementById('bodyContent') : document.getElementsByTagName('body')[0];
	var lis = bod.getElementsByTagName('li');
	if (lis.length == 0)
		return;

	//iterate
	var rightrx = /^.*?User\:.*? from (.*?) to (.*?) \u200E.*?$/i; //the regex used to grab the Special:Log/rights changes
	for (var i = 0; i < lis.length; i++) {
		if (rightsLogOnly) {
			//Special:Log/rights
			var oldr = gettext(lis[i]).replace(rightrx, '$1').replace(/\, /g, ' ');
			var newr = gettext(lis[i]).replace(rightrx, '$2').replace(/\, /g, ' ');
			var oldrl = oldr.split(' ');
			var newrl = newr.split(' ');
			for (var j = 0; j < oldrl.length; j++) {
				for (var k = 0; k < newrl.length; k++) {
					if (oldrl[j] == newrl[k]) {
						oldrl[j] = '';
						newrl[k] = '';
					}
				}
			}
			var remr = oldrl.join(' ');
			var addr = newrl.join(' ');
			switch (type) {
				case 0:
					var look = addr;
					break;
				case 1:
					var look = remr;
					break;
				case 2:
					var look = remr + ' ' + addr;
					break;
				case 3:
					var look = oldr + ' ' + newr;
					break;
			}
		} else {
			//Any other list of <li> objects
			var look = gettext(lis[i]);
		}
		lis[i].style.display = '';
		lis[i].style.backgroundColor = '';
		if ((look.search(rx) != -1 && !invert) || (look.search(rx) == -1 && invert)) {
			if (hilight) lis[i].style.backgroundColor = '#ffff99';
		}
		else
			if (!hilight) lis[i].style.display = 'none';
	}
}

function gettext(object) {
	if (object.nodeType == 3)
		return object.nodeValue;
	var txt = [];
	var i = 0;
	while (object.childNodes[i]) {
		txt[txt.length] = gettext(object.childNodes[i]);
		i++;
	}
	return txt.join('');
}

function queryString(p) {
	return mw.util.getParamValue(p);
}
// </source>