Kang-min Liu - Widget.TableOfContentGenerator-0.02

Documentation | Source

NAME

TableOfContentGenerator - Generate a table of content from DOM.

SYNOPSIS

    <!-- Some content -->
    <div id="content">
      <h1>Foo</h1>
      <p>Tincidunt aliquam eu te vulputate volutpat nulla nostrud dignissim
        odio feugait. Aliquam praesent ut luptatum ipsum.</p>
      <h1>Bar</h1>
      <p>Eu, nulla nulla dignissim dignissim, ut eum. Consequat delenit dolore
        feugiat ea et; in hendrerit, eum facilisis.</p>
    </div>

    <!-- Auto-generate a toc div according to h1 tag in div#content -->
    <script type="text/javascript">
        new Widget.TableOfContentGenerator("h1","content");
    </script>

DESCRIPTION

A table of content is usually a handy widget to navigate through long pages. This helps generating that.

KNOWN ISSUES

So far the only way to use this module is to put the <script> element after the actuall content. It should be more dynamic to be more adaptable.

AUTHOR

Kang-min Liu, <gugod@gugod.org>

COPYRIGHT

Copyright (c) 2006 Kang-min Liu. All rights reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as the Perl programming language (your choice of GPL or the Perl Artistic license).

if ( typeof Widget == "undefined" ) {
   Widget = {};
};

Widget.TableOfContentGenerator = function(tag, baseElemId) {
   this.tag        = tag;
   this.baseElemId = baseElemId;
   this.anchorCount = 0;
   this.generate();
};

Widget.TableOfContentGenerator.VERSION = '0.02';

proto = Widget.TableOfContentGenerator.prototype;

proto.generate = function() {
   var list = this.collect();
   var output = '<div class="table-of-content"><ul>';
   for (var i=0; i < list.length; i++) {
      output +=
         '<li><a href="' + list[i].link + '">' + list[i].title + "</a></li>\n";
   }
   output += "</ul></div>\n";
   document.write(output);
};

proto.collect = function() {
   var baseElem = document.getElementById(this.baseElemId);
   var anchors  = baseElem.getElementsByTagName(this.tag);
   var list = [];
   for (var i = 0; i < anchors.length ; i++ ) {
      var title = anchors[i].childNodes[0].nodeValue;
      var anchorName = this.genAnchorName(title);
      this.insertAnchor(anchors[i], anchorName);
      list.push({ "title": title , "link": "#" + anchorName });
   }
   return list;
}

proto.insertAnchor = function(elem, anchorName) {
   var parent = elem.parentNode;
   var aElem  = document.createElement("a");
   aElem.name = anchorName;
   parent.insertBefore(aElem, elem);
}

proto.genAnchorName = function(title) {
   title = title.replace(/[^A-Za-z]/g,"");
   if ( title.length == 0 ) {
      title = "toc-anchor";
   }
   title += (this.anchorCount++);
   return title;
}

/*
var tocgen = new Widget.TableOfContentGenerator("h1","content");

tocgen.generate();

*/