Insert a table of contents (TOC) which summarizes all headings of a page.
It provides quick access to all headings of the page. At each heading in the page, a back-to-top is inserted.
--DF, Jun 2004

Help Request...#

This works great, but since I've started using FireFox the .css defined for this TOC feature just don't render properly. Has anyone got a set fo css for this feature that works on FireFox as well as the 'other' browsers? (I guess this points to a FireFox javascript/css render bug? Thanks for any clues --JohnV

Seems to work ok on my firefox. Could you give some more details. --DF

Okay, I'm using FireFox 1.0 (latest) and the 'default' template with this bit of javascript added. I wholesale replaced the jspwiki.css of the 'default' template with the one from the 'BrushedTemplate' (This is on a scratch site where I try stuff out before rolling it out to all the others). So I create a page and use:

%%insert-toc
%%
With no caption, and of course some headings and other text on the page. The table of contexts gets built okay, but (and this is the frustrating part) sometimes the toc entries are rendered with the raw H1, H2, etc styles, not the ones defined in the .css, as I said, sometimes. Othertimes they render out all okay and look correct. There isn't much to go on here, I've several pages that have toc's on them, when firefox isn't rendering them correctly, none of them render right. So of course I exit firefox and restart it and (sometimes) they render right. I think this points to a firefox issue not so much as anything wrong with the .js or .css for this feature; I was just wondering if maybe someone had a 'magical', "oh yeah just tickle the .css like this and it will always render okay" sort of 'solution'. Right-clicking and viewing the source for the page doesn't show the .js modified DOM, but rather the original from the server before the .js was run. Oh well. --JohnV (go ahead and this this whole help request if there's not anything to be done about it.)

You can always use firefox's TOOLS | DOMinspector to see whether the .js did it's job alright. -- DF

Usage#

Put a marker on the page where you need a TOC to be inserted (e.g. long FAQ pages etc.) If you need, you can put a TOC caption inside the markers.

        %%insert-toc
        Table-of-content-caption
        %%

How does it work#

After loading the page, a set of javascript routines are triggered when they encounter the <div class="insert-toc"> element. All page headings (!, !!, !!!) are copied into a <div class="toc"> element. Additionaly, each heading in the body of the page gets a hyperlink back to the top of the page.

You can alter the formatting of the TOC via the jspwiki.css selectors .toc and .top.

What you need to do:

  • put some javascript to insert the toc when loading the page [1]
  • put some .css code in template/<YourWikiTemplate>/jspwiki.css [2]

[#1] TOC Javascript support routines

// Insert a TOC in the body of the wiki page summarising all H1,H2,H3,H4. 
// Insert TOP of page hyperlinks at each H1,H2,H3,H4
// (idea based on SearchHighlight javascript)
// If multiple headers have same text, anchor will always point to the first one.
var tocHeaderTag = new Array();
var tocEntries   = new Array();
var tocHREF      = new Array();
var tocSize      = 0;

// validateTOC is called after loading the page
function validateTOC() 
{
  if (!document.createElement) return;

  // find a <div class="insert-toc"> element
  var divArr = document.getElementsByTagName("div");
  if (!divArr) return;
  
  for (i=0; i<divArr.length; i++) 
  {
    if ( divArr[i].className == "insert-toc" )
    {
        showTOC(divArr[i]);
        return; //support one TOC per page
    } txa
  }  
}


function showTOC(tocCaption)
{
  tocEntries   = new Array();
  tocHeaderTag = new Array();
  tocSize      = 0;

  // put all H1,H2,H3,H4 elements in the tocEntries array
  var pn = tocCaption.parentNode;
  showTocEntries(pn,tocCaption,false);
    
  if (tocSize == 0 ) return;
  
  var nodeBefore    = tocCaption.childNodes[0]; 
  var nodeTOC       = document.createElement("div");   
  nodeTOC.className = "toc";   

  for (var i=0; i<tocSize; i++) 
  {
    var nodeHX      = document.createElement(tocHeaderTag[i]);

    // enclose the toc entries in <a href="#xyz">text</a>
    var nodeAnchor  = document.createElement("a");
    nodeAnchor.setAttribute ("href", "#"+tocHREF[i] );

    var nodeTocText = document.createTextNode(tocEntries[i]);
    nodeAnchor.appendChild(nodeTocText);
    nodeHX.appendChild(nodeAnchor);
    nodeTOC.appendChild(nodeHX);
  }

  var nxt = tocCaption.nextSibling;
  pn.insertBefore(nodeTOC, nxt);

}


function showTocEntries(node,skipCaption,headerFound)
{
  var makeToc = false;
  
  if ( node == skipCaption)  return;
  
  if (  (node.nodeName == "H1") 
     || (node.nodeName == "H2")
     || (node.nodeName == "H3") 
     || (node.nodeName == "H4"))
  {
    headerFound           = true;
    makeToc               = true;
    tocHeaderTag[tocSize] = node.nodeName; 
    tocEntries[tocSize]   = "";  
    tocHREF[tocSize]      = "";  
  }

  /* get anchor name of first <A> inside the header */
  if ( (headerFound) && (node.nodeName == "A") && (tocHREF[tocSize] == "") )
  {
    tocHREF[tocSize] = node.getAttribute("name");
  }
  
  /* concat all text child text nodes of the header element */
  if ( (headerFound) && (node.nodeType == 3) )
  { 
    tocEntries[tocSize] += node.nodeValue ; 
  }

  if (node.hasChildNodes) /* walk the tree */
  {
    for (var i=0; i<node.childNodes.length; i++) 
    { 
      showTocEntries(node.childNodes[i],skipCaption,headerFound);
    }
  }
  
  if (makeToc)  /* add a TOP OF PAGE link */
  {
    var nodeTOP       = document.createElement("a");
    nodeTOP.innerHTML = "&raquo;TOP" ;
    nodeTOP.className = "top"; 
    nodeTOP.setAttribute ("href", "#Top");    
    node.appendChild(nodeTOP);    
    tocSize++;
  }
  	
}

In the default jspwiki template, the window onload function is defined in search_highlight.js,
You'll need to extend it with a call to the validateTOC function.

function runOnLoad 
{
  googleSearchHighlight();
  validateTOC();
}
window.onload = runOnLoad;

[#2] TOC Stylesheet loader: add this to template/<YourWikiTemplate>/jspwiki.css

.insert-toc  /* toc caption */
    {  }

.toc
    { padding:     5px;
      border:      1px dotted blue;
      margin:      1em 1em 1em 1em;
    }
   
   
.toc h1 { margin: 0 0 0 0em; }
.toc h2 { margin: 0 0 0 1em; }
.toc h3 { margin: 0 0 0 2em; }
.toc h4 { margin: 0 0 0 3em; }


.toc a:link,
.toc a:visited
   { font-size:       small;         
     font-weight:     normal;
   }

a.top:link, 
a.top:visited 
   { margin-left:     1em;
     vertical-align:  middle;
     font-size:       xx-small;   
   }  

Example#

Back to BrushedTemplate

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-10) was last changed on 12-Oct-2007 13:56 by 83.138.0.70