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.
if (window.RCNSTDefaultToVisible === undefined)
var RCNSTDefaultToVisible = true;
if (window.RCNSTStartHidden === undefined) var RCNSTStartHidden = [];
if (window.RCNSTStartVisible === undefined) var RCNSTStartVisible = [];
if (window.RCNSTControlsID === undefined) var RCNSTControlsID = 'rcnst';
if (window.RCNSTClass === undefined) var RCNSTClass = 'rcnst';
if (window.RCNSTMain === undefined) var RCNSTMain = '(Main)';
if (window.RCNSTToggleAllLabel === undefined)
var RCNSTToggleAllLabel = 'toggle all';
if (window.RCNSTInvertLabel === undefined)
var RCNSTInvertLabel = 'invert selection';
if (window.RCNSTRestoreLabel === undefined)
var RCNSTRestoreLabel = 'restore default';
if (window.hasClass === undefined) {
var hasClass = (function () {
var reCache = {};
return function (element, className) {
return (reCache[className] ? reCache[className] : (reCache[className] =
new RegExp("(?:\\s|^)" + className + "(?:\\s|$)")))
.test(element.className);
};
})();
}
function nextElement (e) {
do e = e.nextSibling;
while (e !== null && e.nodeType != 1);
return e;
}
function previousElement (e) {
do e = e.previousSibling;
while (e !== null && e.nodeType != 1);
return e;
}
if (!Array.indexOf) {
Array.prototype.indexOf = function (o) {
var i = this.length;
while (i--) if (this[i] === o) return i;
return -1;
};
}
var RCNST = {};
RCNST.getDefault = function (changeType) {
if (RCNSTDefaultToVisible)
return RCNSTStartHidden.indexOf(changeType) == -1;
else
return RCNSTStartVisible.indexOf(changeType) != -1;
};
RCNST.classRegex = new RegExp('\\b' + RCNSTClass + '\\b', 'g');
RCNST.getChangeType = function (change) {
var result;
var lnks = change.getElementsByTagName('a');
var lnk = lnks[0].firstChild.nodeValue;
var isEdit = false;
if (RCNST.enh) {
if (lnks[0].parentNode.firstChild.nodeValue.indexOf('(') == -1)
isEdit = true;
} else {
if (lnk == 'diff' || lnk == 'hist') {
var isEdit = true;
if (lnk == 'diff') lnk = 2;
else lnk = 1; // new page
lnk = lnks[lnk].firstChild.nodeValue;
}
}
if (isEdit) {
// work out namespace
var colon = lnk.indexOf(':');
if (colon == -1) result = RCNSTMain;
else result = lnk.substring(0, colon);
} else result = lnk; // log
return result;
};
RCNST.toggle = function (changeType) {
// show/hide changes of given type according to corresponding checkbox
var show = RCNST.checkboxes[changeType].checked;
var changes = RCNST.changes[changeType];
if (show) var reg = RCNST.classRegex;
for (var i = 0; i < changes.length; i++) {
if (RCNST.enh) {
var div = nextElement(changes[i]);
if (div !== null && div.tagName.toLowerCase() == 'div') {
// also do the same for the subchanges
if (show)
// remove class
div.className = div.className.replace(reg, ' ');
else div.className += ' ' + RCNSTClass; // add class
}
}
if (show)
// remove class
changes[i].className = changes[i].className.replace(reg, ' ');
else changes[i].className += ' ' + RCNSTClass; // add class
}
};
RCNST.smartToggle = function (changeType, show) {
// set changes of given type to given visibility if not already
var c = RCNST.checkboxes[changeType];
var shown = c.checked;
if (shown != show) {
c.checked = show;
RCNST.toggle(changeType);
}
};
RCNST.toggleAll = function () {
// if any types are hidden, show them all, else hide them all
var show = false;
for (var changeType in RCNST.checkboxes) {
if (!RCNST.checkboxes[changeType].checked) {
show = true;
break;
}
}
for (var changeType in RCNST.checkboxes)
RCNST.smartToggle(changeType, show);
RCNST.updateHeadings();
};
RCNST.invert = function () {
for (var changeType in RCNST.checkboxes)
RCNST.smartToggle(changeType, !RCNST.checkboxes[changeType].checked);
RCNST.updateHeadings();
};
RCNST.restore = function () {
for (var changeType in RCNST.checkboxes)
RCNST.smartToggle(changeType, RCNST.getDefault(changeType));
RCNST.updateHeadings();
};
RCNST.updateHeadings = function () {
// hide headings if all changes in them are hidden, else show them
var enh = RCNST.enh;
var reg = RCNST.classRegex;
var h4s = document.getElementsByTagName('h4');
for (var i = 0; i < h4s.length; i++) {
var h4 = h4s[i];
// check it's a valid header and get change list
var section = nextElement(h4);
if (section === null || section.tagName === undefined) continue;
var sectionTag = section.tagName.toLowerCase();
if (enh) {
if (sectionTag != 'div') continue;
var changes = getElementsByClassName(section, 'table',
'mw-enhanced-rc');
} else {
if (sectionTag != 'ul' || !hasClass(section, 'special')) continue;
var changes = section.getElementsByTagName('li');
}
if (changes.length == 0) continue;
// check changes under this heading
var show = false;
for (var j = 0; j < changes.length; j++) {
if (changes[j].parentNode !== section) continue;
if (!hasClass(changes[j], RCNSTClass)) {
show = true;
break;
}
}
if (show) h4.className = h4.className.replace(reg, ' ');
else if (!hasClass(h4, RCNSTClass)) h4.className += ' ' + RCNSTClass;
}
};
RCNST.init = function () {
if (!hasClass(document.body, 'page-Special_RecentChanges')
&& !hasClass(document.body, 'page-Special_Recentchanges')
&& !hasClass(document.body, 'page-Special_Watchlist'))
return;
// compile per-type lists of RC changes
var changes = {};
RCNST.changes = changes;
var uls = getElementsByClassName(document, 'ul', 'special');
if (uls.length) {
// normal RC
RCNST.enh = false;
for (var i = 0; i < uls.length; i++) {
var lis = uls[i].getElementsByTagName('li');
for (var j = 0; j < lis.length; j++) {
var change = lis[j];
var changeType = RCNST.getChangeType(change);
if (changes[changeType] === undefined)
changes[changeType] = [change];
else changes[changeType].push(change);
}
}
} else {
var tbls = getElementsByClassName(document, 'table', 'mw-enhanced-rc');
if (tbls.length) {
// enhanced RC
RCNST.enh = true;
for (var i = 0; i < tbls.length; i++) {
var tbl = tbls[i];
var tds = tbl.getElementsByTagName('td');
if (!hasClass(tds[0], 'mw-enhanced-rc')) continue;
var changeType = RCNST.getChangeType(tds[1]);
if (changes[changeType] === undefined)
changes[changeType] = [tbl];
else changes[changeType].push(tbl);
}
} else return; // no changes
}
// add controls to page
var rcoptions = getElementsByClassName(document, '*', 'rcoptions');
if (rcoptions.length) {
// put with the other controls
rcoptions[0].appendChild(document.createElement('hr'));
var controls = document.createElement('span');
rcoptions[0].appendChild(controls);
} else {
// put before the first day heading
var h4s = document.getElementsByTagName('h4');
for (var i = 0; i < h4s.length; i++) {
var e = nextElement(h4s[i]);
if (e !== null && e.tagName.toLowerCase() == 'ul'
&& hasClass(e, 'special')) {
var controls = document.createElement('div');
h4s[i].parentNode.insertBefore(controls, h4s[i]);
break;
}
}
// if there are no day headings, I have no idea what's going on, so
// just don't show them
}
controls.id = RCNSTControlsID;
// create ordered list of change types
var changeTypes = [];
// namespaces first
var nsSelect = document.getElementById('namespace');
if (nsSelect !== null) {
var optionList = nsSelect.getElementsByTagName('option');
for (var i = 0; i < optionList.length; i++) {
if (optionList[i].value == '0') var ns = RCNSTMain;
else var ns = optionList[i].firstChild.nodeValue;
if (changes[ns] !== undefined) changeTypes.push(ns);
}
}
// then logs
var toSort = [];
for (changeType in changes)
if (changeTypes.indexOf(changeType) == -1) toSort.push(changeType);
toSort.sort();
changeTypes = changeTypes.concat(toSort);
// then create checkboxes in this order
var checkboxes = {};
RCNST.checkboxes = checkboxes;
for (var i = 0; i < changeTypes.length; i++) {
var c = document.createElement('input');
checkboxes[changeTypes[i]] = c;
c.type = 'checkbox';
c.onclick = function () {
RCNST.toggle(this.nextSibling.firstChild.nodeValue);
RCNST.updateHeadings();
};
c.checked = true;
controls.appendChild(c);
var label = document.createElement('label');
label.appendChild(document.createTextNode(changeTypes[i]));
controls.appendChild(label);
}
RCNST.restore();
// add buttons to controls
function addButton (label, onclick) {
var button = document.createElement('input');
button.type = 'button';
button.value = label;
button.onclick = RCNST[onclick];
controls.appendChild(button);
}
addButton(RCNSTToggleAllLabel, 'toggleAll');
addButton(RCNSTInvertLabel, 'invert');
addButton(RCNSTRestoreLabel, 'restore');
if (RCNST.enh) {
// replace enhanced RC event for the arrow things
window.toggleVisibility = function(idNumber) {
var openarrow = document.getElementById("mw-rc-openarrow-"+idNumber);
var closearrow = document.getElementById("mw-rc-closearrow-"+idNumber);
var subentries = document.getElementById("mw-rc-subentries-"+idNumber);
if (openarrow.className == 'mw-changeslist-expanded') {
openarrow.className = 'mw-changeslist-hidden';
closearrow.className = 'mw-changeslist-expanded';
subentries.className = subentries.className.replace(
/\bmw-changeslist-hidden\b/, 'mw-changeslist-expanded');
} else {
openarrow.className = 'mw-changeslist-expanded';
closearrow.className = 'mw-changeslist-hidden';
subentries.className = subentries.className.replace(
/\bmw-changeslist-expanded\b/, 'mw-changeslist-hidden');
}
};
}
};
// initialise on page load
if (window.domReady !== undefined) domReady(RCNST.init);
else $(RCNST.init);