User:Greenpickle/monobook.js: Difference between revisions
Jump to navigation
Jump to search
Greenpickle (talk | contribs) No edit summary |
Greenpickle (talk | contribs) No edit summary |
||
Line 1: | Line 1: | ||
document.write('<script type="text/javascript" src="http://en.wikipedia.org/w/index.php?title=User:Cacycle/wikEdDiff.js&action=raw&ctype=text/javascript&"><\/script>\n<script type="text/javascript" src="http://en.wikipedia.org/w/index.php?title=User:Lupin/popups.js&action=raw&ctype=text/javascript"><\/script>'); | document.write('<script type="text/javascript" src="http://en.wikipedia.org/w/index.php?title=User:Cacycle/wikEdDiff.js&action=raw&ctype=text/javascript&"><\/script>\n<script type="text/javascript" src="http://en.wikipedia.org/w/index.php?title=User:Lupin/popups.js&action=raw&ctype=text/javascript"><\/script>'); | ||
//document.write('<script type="text/javascript" src="http://pikminwiki.com/index.php?title=User:Greenpickle/rcnst.js&action=raw&ctype=text/javascript"><\/script>'); | |||
// initial selected types; use the string in RCNSTMain for main | |||
RCNSTDefaultToVisible = true; | |||
RCNSTStartHidden = ['User', 'User talk', 'User blog', 'User blog talk', 'User blog comment', 'User blog comment talk', 'User avatar log', 'User creation log']; | |||
RCNSTStartVisible = []; | |||
// id and class used in elements | |||
RCNSTControlsID = 'rcnst'; | |||
document. | RCNSTClass = 'rcnst'; | ||
// strings used in the created elements | |||
RCNSTMain = '(Main)'; | |||
RCNSTToggleAllLabel = 'toggle all'; | |||
RCNSTInvertLabel = 'invert selection'; | |||
RCNSTRestoreLabel = 'restore default'; | |||
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 firstLink = lnks[0].firstChild.nodeValue; | |||
if (firstLink == 'diff' || firstLink == 'hist') { | |||
// edit | |||
if (firstLink == 'diff') var lnk = 2; | |||
else | |||
//new page | |||
var lnk = 1; | |||
// work out namespace | |||
lnk = lnks[lnk].firstChild.nodeValue; | |||
var colon = lnk.indexOf(':'); | |||
if (colon == -1) result = RCNSTMain; | |||
else result = lnk.substring(0, colon); | |||
} else | |||
// log | |||
result = firstLink; | |||
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 (show) | |||
// remove class | |||
changes[i].className = changes[i].className.replace(reg, ' '); | |||
else | |||
// add class | |||
changes[i].className += ' ' + RCNSTClass; | |||
} | |||
}; | |||
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 uls = getElementsByClassName(document, 'ul', 'special'); | |||
var reg = RCNST.classRegex; | |||
for (var i = 0; i < uls.length; i++) { | |||
var h4 = previousElement(uls[i]); | |||
if (h4.tagName.toLowerCase() != 'h4') | |||
// not a heading | |||
continue; | |||
var lis = uls[i].getElementsByTagName('li'); | |||
var hide = true; | |||
// check changes under this heading | |||
for (var j = 0; j < lis.length; j++) { | |||
if (!hasClass(lis[j], RCNSTClass)) { | |||
hide = false; | |||
break; | |||
} | |||
} | |||
if (hide) { | |||
if(!hasClass(h4, RCNSTClass)) h4.className += ' ' + RCNSTClass; | |||
} else h4.className = h4.className.replace(reg, ' '); | |||
} | |||
}; | |||
RCNST.init = function () { | |||
if (!hasClass(document.body, 'page-Special_RecentChanges') && | |||
!hasClass(document.body, 'page-Special_Recentchanges')) | |||
return; | |||
// 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; | |||
// compile per-type lists of RC changes | |||
var changes = {}; | |||
RCNST.changes = changes; | |||
var uls = getElementsByClassName(document, 'ul', 'special'); | |||
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); | |||
} | |||
} | |||
// 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 = RCNST.getDefault(changeTypes[i]); | |||
controls.appendChild(c); | |||
var label = document.createElement('label') | |||
label.appendChild(document.createTextNode(changeTypes[i])); | |||
controls.appendChild(label); | |||
} | |||
// hide changes for initially disabled types | |||
for (changeType in checkboxes) | |||
if (!checkboxes[changeType].checked) RCNST.toggle(changeType); | |||
RCNST.updateHeadings(); | |||
// 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'); | |||
}; | |||
// initialise on page load | |||
if (window.addEventListener !== undefined) | |||
addEventListener('load', RCNST.init, false); | |||
else if (window.attachEvent !== undefined) | |||
attachEvent('onload', RCNST.init); | |||
else if (window.addOnloadHook !== undefined) | |||
addOnloadHook(RCNST.init); | |||
else onload = RCNST.init; |
Revision as of 18:09, November 8, 2010
document.write('<script type="text/javascript" src="http://en.wikipedia.org/w/index.php?title=User:Cacycle/wikEdDiff.js&action=raw&ctype=text/javascript&"><\/script>\n<script type="text/javascript" src="http://en.wikipedia.org/w/index.php?title=User:Lupin/popups.js&action=raw&ctype=text/javascript"><\/script>');
//document.write('<script type="text/javascript" src="http://pikminwiki.com/index.php?title=User:Greenpickle/rcnst.js&action=raw&ctype=text/javascript"><\/script>');
// initial selected types; use the string in RCNSTMain for main
RCNSTDefaultToVisible = true;
RCNSTStartHidden = ['User', 'User talk', 'User blog', 'User blog talk', 'User blog comment', 'User blog comment talk', 'User avatar log', 'User creation log'];
RCNSTStartVisible = [];
// id and class used in elements
RCNSTControlsID = 'rcnst';
RCNSTClass = 'rcnst';
// strings used in the created elements
RCNSTMain = '(Main)';
RCNSTToggleAllLabel = 'toggle all';
RCNSTInvertLabel = 'invert selection';
RCNSTRestoreLabel = 'restore default';
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 firstLink = lnks[0].firstChild.nodeValue;
if (firstLink == 'diff' || firstLink == 'hist') {
// edit
if (firstLink == 'diff') var lnk = 2;
else
//new page
var lnk = 1;
// work out namespace
lnk = lnks[lnk].firstChild.nodeValue;
var colon = lnk.indexOf(':');
if (colon == -1) result = RCNSTMain;
else result = lnk.substring(0, colon);
} else
// log
result = firstLink;
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 (show)
// remove class
changes[i].className = changes[i].className.replace(reg, ' ');
else
// add class
changes[i].className += ' ' + RCNSTClass;
}
};
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 uls = getElementsByClassName(document, 'ul', 'special');
var reg = RCNST.classRegex;
for (var i = 0; i < uls.length; i++) {
var h4 = previousElement(uls[i]);
if (h4.tagName.toLowerCase() != 'h4')
// not a heading
continue;
var lis = uls[i].getElementsByTagName('li');
var hide = true;
// check changes under this heading
for (var j = 0; j < lis.length; j++) {
if (!hasClass(lis[j], RCNSTClass)) {
hide = false;
break;
}
}
if (hide) {
if(!hasClass(h4, RCNSTClass)) h4.className += ' ' + RCNSTClass;
} else h4.className = h4.className.replace(reg, ' ');
}
};
RCNST.init = function () {
if (!hasClass(document.body, 'page-Special_RecentChanges') &&
!hasClass(document.body, 'page-Special_Recentchanges'))
return;
// 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;
// compile per-type lists of RC changes
var changes = {};
RCNST.changes = changes;
var uls = getElementsByClassName(document, 'ul', 'special');
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);
}
}
// 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 = RCNST.getDefault(changeTypes[i]);
controls.appendChild(c);
var label = document.createElement('label')
label.appendChild(document.createTextNode(changeTypes[i]));
controls.appendChild(label);
}
// hide changes for initially disabled types
for (changeType in checkboxes)
if (!checkboxes[changeType].checked) RCNST.toggle(changeType);
RCNST.updateHeadings();
// 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');
};
// initialise on page load
if (window.addEventListener !== undefined)
addEventListener('load', RCNST.init, false);
else if (window.attachEvent !== undefined)
attachEvent('onload', RCNST.init);
else if (window.addOnloadHook !== undefined)
addOnloadHook(RCNST.init);
else onload = RCNST.init;