2 * Copyright (C) 2006 Merjis Ltd.
3 * $Id: folding.js,v 1.1 2006/08/17 11:19:58 rich Exp $
5 * For very long pages, you can use this Javascript to provide
6 * folding headings to make viewing the page more manageable.
8 * To install this code:
9 * (1) You must have the "manage site" permission.
10 * (2) Go to Sitewide settings, click Edit these settings, and in
11 * the Page bug section, add or append the following Javascript
13 * <script src="/_js/folding.js" type="text/javascript"></script>
14 * (3) Edit the page where you want folding to appear, and set
15 * the CSS class to "folding".
18 // http://domscripting.com/blog/display/18
19 function getElementsByClass (node, searchClass, tag)
21 var classElements = new Array();
22 var els = node.getElementsByTagName (tag);
23 var pattern = new RegExp ("\\b"+searchClass+"\\b");
24 for (i = 0, j = 0; i < els.length; i++) {
25 if (pattern.test (els[i].className)) {
26 classElements[j] = els[i];
33 function setTextContent (text, content)
35 // Not sure if this is even possible in IE6.
36 if (text.textContent) text.textContent = content;
39 function setOnClick (node, f)
41 // if (!node.attachEvent) node.onclick = f;
42 // else node.attachEvent ("onclick", f);
46 // http://joust.kano.net/weblog/archive/2005/08/08/a-huge-gotcha-with-javascript-closures/
47 // http://calculist.blogspot.com/2005/12/gotcha-gotcha.html
48 function createShowFunction (text, plus, nodes)
50 return function (evt) {
51 // Restore the old display style.
52 for (var k = 0; k < nodes.length; ++k) {
55 node.style.display = node.getAttribute ("displayold");
57 setTextContent (text, "[-]");
58 setOnClick (plus, createHideFunction (text, plus, nodes));
62 function createHideFunction (text, plus, nodes)
64 return function (evt) {
65 // Set all the nodes to display none, but remember the old
67 for (var k = 0; k < nodes.length; ++k) {
70 node.setAttribute ("displayold", node.style.display);
71 node.style.display = "none";
74 setTextContent (text, "[+]");
75 setOnClick (plus, createShowFunction (text, plus, nodes));
79 function set_up_folding ()
81 var divs = getElementsByClass (document, "folding", "div");
82 for (var d = 0; d < divs.length; ++d) {
84 var children = div.childNodes;
85 // List of child nodes is something like H3, n, n, H3, n, n, n, ...
86 // Add a button before each H3 which hides/shows the subsequent
87 // nodes up to but not including the next H3.
88 for (var i = 0; i < children.length; ++i) {
90 if (h3.nodeName == "H3") {
92 while (j < children.length && children[j].nodeName != "H3") j++;
93 // children i to j exclusive should be shown/hidden.
94 // Copy them to an array called 'nodes'.
95 var nodes = new Array ();
96 for (var k = i+1; k < j; ++k) {
97 var child = children[k];
98 nodes[k-(i+1)] = child;
101 // Create the +/- control.
102 var plus = document.createElement ("div");
103 plus.setAttribute ("class", "foldingcontrol");
104 var text = document.createTextNode ("[+]");
105 plus.appendChild (text);
107 // Create functions to show/hide the nodes.
108 var show = createShowFunction (text, plus, nodes);
109 var hide = createHideFunction (text, plus, nodes);
113 // Place the '+' button before the h3.
114 div.insertBefore (plus, h3);
115 setOnClick (plus, show);
117 // Skip directly to next h3.