memory alpha

I, and others, didn't like the scroll boxes used to shorten the "Appearances" and "References" sections. User:Cid Highwind proposed a way to hide the sections until the user selected to show them (see Forum:Appearances section - suggestion), and I took this idea a little further and wrote a script that allows the trees that contain this information to be collapsed and expanded, while also counting the sub-items so that some meaningful information is immediately available.

Originally, I wrote this to be used only for appearances, but it can be used for other trees as well.

Usage

To use the script, enclose the tree with:

<div class="appear [...]">
* Item
** Item
*** Item
*** Item
** Item
** Item
</div>

The class can be used with other classes, like noicon. There is another special class, nocount, which will not add a count of the sub-items to the end of the branches.

Tweaks

If you don't want the script to run, add this line to your User:/monobook.js:

interactiveTrees = 0;

If you want to have the scroll boxes, add this line to your User:/monobook.css:

.appear{ overflow:auto; height:230px; width:75%; float:left; }

To set the minum number of leaves that can be left open, add this line to your User:/monobook.css: (n is the number of leaves)

smallTreeCount = <n>;

To set the string of text that appears at the top of counted lists, add this line to your User:/monobook.css: (put %d where you want the number to appear)

descriptionString = "<s>";

Example

Interactive Non-interactive (source)

Guy Vardaman appearances as Darien Wallace

Pakled appearances

Q appearances

Guy Vardaman appearances as Darien Wallace

Issues

Source

The source for the version running on MA is in Mediawiki:common.css and Mediawiki:common.js.

Versions

CSS

.hiddenlist { display:none; }
.visiblelist { display:block; }

.listexpand { text-decoration: none; color: #66BBFF; }
.listexpand:hover { text-decoration: underline; color: #66BBFF; }

JS

// Start "Hidden appearances section/interactive tree" script; by [[User:Bp]]
// -----
function toggleAppearancesPane(eid) {
	e = document.getElementById(eid);
	if (e) { e.className = (e.className == "hiddenlist") ? "visiblelist" : "hiddenlist"; }
}

function showAppearancesPane(eid) {
	e = document.getElementById(eid);
	if (e) { e.className = "visiblelist"; }
}

function hideAppearancesPane(eid) {
	e = document.getElementById(eid);
	if (e) { e.className = "hiddenlist"; }
}
// -----

var tree = 0;
var pane = 0;
var paneListForThisTree = new Array();
var descriptionString = new String("This list contains %d items."); //%d is where the number of items is inserted

var smallTreeCount = 8; // less leaves than this, the tree will be open at first
var interactiveTrees = 1; // set this to 0 in user.js to turn this off

function button(text,onclick,cls) {
	var b = document.createElement('a');
	b.innerHTML = text;
	b.href="javascript:"+onclick;
	b.className = cls;
	return b;
}

function recursiveCountAndMark(e, depth, nocount) {
	var si = e.firstChild;
	var total = 0;
	while(si) {
		var tn = (si.tagName) ? si.tagName.toLowerCase() : '';
		if (tn == "li") { total++; }
		var subtotal = recursiveCountAndMark(si, depth+1, nocount);
		if (tn == "ul" || tn == "ol") {
			if (depth > 1) {
				si.id = "Pane" + pane++;
				paneListForThisTree.push(si.id);
				si.className = "hiddenlist";

				si.parentNode.insertBefore(document.createTextNode('('), si);
				si.parentNode.insertBefore(button( (nocount) ? "+/-" : subtotal, "toggleAppearancesPane(\""+si.id+"\")", "listexpand"), si);
				si.parentNode.insertBefore(document.createTextNode(')'), si);
				total--; // don't count the li that this ul/ol is in
			} else {
				// we are finished and this is the top ul/ol
				if (subtotal < smallTreeCount) { // this small enough they can be visible right away
					for (var i=0;i<paneListForThisTree.length;i++) {
						toggleAppearancesPane(paneListForThisTree[i]);
					}
				}
				var allonexec = '{';
				var alloffexec = '{';
				for (var i=0;i<paneListForThisTree.length;i++) {
					allonexec += "showAppearancesPane(\""+paneListForThisTree[i]+"\"); ";
					alloffexec += "hideAppearancesPane(\""+paneListForThisTree[i]+"\"); ";
				}
				allonexec += '}'; alloffexec += '}';

				var ds = (nocount) ? "" : descriptionString.replace(/\%d/g, subtotal);

				si.parentNode.insertBefore(document.createTextNode(ds + ' ('), si);
				si.parentNode.insertBefore(button("show all", allonexec, "listexpand"), si);
				si.parentNode.insertBefore(document.createTextNode(' | '), si);
				si.parentNode.insertBefore(button("hide all", alloffexec, "listexpand"), si);
				si.parentNode.insertBefore(document.createTextNode(')'), si);
			}
		}
		total += subtotal;
		si = si.nextSibling;
	}
	return total;
}

function doAppearancesTrees() {
	if (!interactiveTrees) { return; }

	var divs = document.getElementsByTagName("div");
	for (var i = 0; i < divs.length; i++) {
		if (divs[i].className.match(/\bappear\b/)) {
			recursiveCountAndMark(divs[i], 0, (divs[i].className.match(/\bnocount\b/)) ? 1 : 0);
			paneListForThisTree = new Array();
			tree++;
		}
	}

	// fix a bug noticed by renegade54
	// jump to the named anchor again
	if (window.location.hash && tree > 0) {
		// still won't work 100% in safari and khtml
		if (navigator.userAgent.indexOf("MSIE") != -1) {
			window.location = window.location.hash; // -- causes Firefox to fire onload events
		} else {
			window.location.hash = window.location.hash;
		}
	}

}

hookEvent("load", doAppearancesTrees);

On other wikis

A couple people asked to use it on their wikis, which is nice. I'm glad it's useful to someone. As I explained to them, it is CC-by-NC 2.5, like all of MA, so most wikis that are GFDL or GPL or whatever need to make that explicit, and comply. Also, tell me so I can put it on the list.