Annotation of hatari/doc/toc.js, revision 1.1.1.1

1.1       root        1: /** toc.js
                      2: 
                      3:     This is a simplified version of the scipt "generated_toc.js" written by:
                      4:             Stuart Langridge, July 2007
                      5: 
                      6:     The script is licensed under the terms of the MIT license.
                      7:     See the following page for details:
                      8:             http://www.kryogenix.org/code/browser/generated-toc/
                      9: 
                     10:     Generate a table of contents, based on headings in the page.
                     11: 
                     12:     To place the TOC on the page, add
                     13: 
                     14:     <div id="generated-toc"></div>
                     15: 
                     16:     to the page where you want the TOC to appear. If this element
                     17:     is not present, the TOC will not appear.
                     18: 
                     19: */
                     20: 
                     21: generated_toc = {
                     22:   generate: function() {
                     23:     // Identify our TOC element, and what it applies to
                     24:     generate_from = '2';
                     25:     tocparent = document.getElementById('generated-toc');
                     26:     if (!tocparent) {
                     27:       // They didn't specify a TOC element; exit
                     28:       return;
                     29:     }
                     30: 
                     31:     // set top_node to be the element in the document under which
                     32:     // we'll be analysing headings
                     33:     top_node = document.getElementsByTagName('body')[0];
                     34: 
                     35:     // If there isn't a specified header level to generate from, work
                     36:     // out what the first header level inside top_node is
                     37:     // and make that the specified header level
                     38:     if (generate_from == 0) {
                     39:       first_header_found = generated_toc.findFirstHeader(top_node);
                     40:       if (!first_header_found) {
                     41:         // there were no headers at all inside top_node!
                     42:         return;
                     43:       } else {
                     44:         generate_from = first_header_found.toLowerCase().substr(1);
                     45:       }
                     46:     }
                     47: 
                     48:     // add all levels of heading we're paying attention to to the
                     49:     // headings_to_treat dictionary, ready to be filled in later
                     50:     headings_to_treat = {"h6":''};
                     51:     for (var i=5; i>= parseInt(generate_from); i--) {
                     52:       headings_to_treat["h" + i] = '';
                     53:     }
                     54: 
                     55:     // get headings. We can't say
                     56:     // getElementsByTagName("h1" or "h2" or "h3"), etc, so get all
                     57:     // elements and filter them ourselves
                     58:     // need to use .all here because IE doesn't support gEBTN('*')
                     59:     nodes = top_node.all ? top_node.all : top_node.getElementsByTagName('*');
                     60: 
                     61:     // put all the headings we care about in headings
                     62:     headings = [];
                     63:     for (var i=0; i<nodes.length;i++) {
                     64:       if (nodes[i].nodeName.toLowerCase() in headings_to_treat) {
                     65:         // if heading has class no-TOC, skip it
                     66:         if ((' ' + nodes[i].className + ' ').indexOf('no-TOC') != -1) {
                     67:           continue;
                     68:         }
                     69:         headings.push(nodes[i]);
                     70:       }
                     71:     }
                     72: 
                     73:     // make the basic elements of the TOC itself, ready to fill into
                     74:     cur_head_lvl = "h" + generate_from;
                     75:     cur_list_el = document.createElement('ul');
                     76:     tocparent.appendChild(cur_list_el);
                     77: 
                     78:     // now walk through our saved heading nodes
                     79:     for (var i=0; i<headings.length; i++) {
                     80:       this_head_el = headings[i];
                     81:       this_head_lvl = headings[i].nodeName.toLowerCase();
                     82:       if (!this_head_el.id) {
                     83:         // if heading doesn't have an ID, give it one
                     84:         //this_head_el.id = 'heading_toc_' + i;
                     85:         var id = generated_toc.innerText(this_head_el).replace(/[ \/]/g, "_");
                     86:         id = id.replace(/[^a-zA-Z0-9-_]/g, '');
                     87:         this_head_el.id = id;
                     88:       }
                     89: 
                     90:       while(this_head_lvl > cur_head_lvl) {
                     91:         // this heading is at a lower level than the last one;
                     92:         // create additional nested lists to put it at the right level
                     93: 
                     94:         // get the *last* LI in the current list, and add our new UL to it
                     95:         var last_listitem_el = null;
                     96:         for (var j=0; j<cur_list_el.childNodes.length; j++) {
                     97:           if (cur_list_el.childNodes[j].nodeName.toLowerCase() == 'li') {
                     98:             last_listitem_el = cur_list_el.childNodes[j];
                     99:           }
                    100:         }
                    101:         if (!last_listitem_el) {
                    102:           // there aren't any LIs, so create a new one to add the UL to
                    103:           last_listitem_el = document.createElement('li');
                    104:         }
                    105:         new_list_el = document.createElement('ul');
                    106:         last_listitem_el.appendChild(new_list_el);
                    107:         cur_list_el.appendChild(last_listitem_el);
                    108:         cur_list_el = new_list_el;
                    109:         cur_head_lvl = 'h' + (parseInt(cur_head_lvl.substr(1,1)) + 1);
                    110:       }
                    111: 
                    112:       while (this_head_lvl < cur_head_lvl) {
                    113:         // this heading is at a higher level than the last one;
                    114:         // go back up the TOC to put it at the right level
                    115:         cur_list_el = cur_list_el.parentNode.parentNode;
                    116:         cur_head_lvl = 'h' + (parseInt(cur_head_lvl.substr(1,1)) - 1);
                    117:       }
                    118: 
                    119:       // create a link to this heading, and add it to the TOC
                    120:       li = document.createElement('li');
                    121:       a = document.createElement('a');
                    122:       a.href = '#' + this_head_el.id;
                    123:       a.appendChild(document.createTextNode(generated_toc.innerText(this_head_el)));
                    124:       li.appendChild(a);
                    125:       cur_list_el.appendChild(li);
                    126:     }
                    127:   },
                    128: 
                    129:   innerText: function(el) {
                    130:     return (typeof(el.innerText) != 'undefined') ? el.innerText :
                    131:           (typeof(el.textContent) != 'undefined') ? el.textContent :
                    132:           el.innerHTML.replace(/<[^>]+>/g, '');
                    133:   },
                    134: 
                    135:   findFirstHeader: function(node) {
                    136:     // a recursive function which returns the first header it finds inside
                    137:     // node, or null if there are no functions inside node.
                    138:     var nn = node.nodeName.toLowerCase();
                    139:     if (nn.match(/^h[1-6]$/)) {
                    140:       // this node is itself a header; return our name
                    141:       return nn;
                    142:     } else {
                    143:       for (var i=0; i<node.childNodes.length; i++) {
                    144:         var subvalue = generated_toc.findFirstHeader(node.childNodes[i]);
                    145:         // if one of the subnodes finds a header, abort the loop and return it
                    146:         if (subvalue) return subvalue;
                    147:       }
                    148:       // no headers in this node at all
                    149:       return null;
                    150:     }
                    151:   },
                    152: 
                    153:   getYPos: function(el) {
                    154:     var y = 0;
                    155:     while (el && !isNaN(el.offsetTop)) {
                    156:         y += el.offsetTop;
                    157:         el = el.parentNode;
                    158:     }
                    159:     return y;
                    160:   },
                    161: 
                    162:   init: function() {
                    163:     // quit if this function has already been called
                    164:     if (arguments.callee.done) return;
                    165: 
                    166:     // flag this function so we don't do the same thing twice
                    167:     arguments.callee.done = true;
                    168: 
                    169:     generated_toc.generate();
                    170: 
                    171:     if (location.hash.length != 0) {
                    172:         // Make sure that the browser scrolled to the right location!
                    173:         var anchor = location.hash.substring(1);
                    174:         var y = generated_toc.getYPos(document.getElementById(anchor));
                    175:         if ('scrollTo' in window) {
                    176:             window.scrollTo(0, y);
                    177:         }
                    178:         else if ('scroll' in window) {
                    179:             window.scroll(0, y);
                    180:         }
                    181:     }
                    182:   }
                    183: };
                    184: 
                    185: /* Run generated_toc.init as soon as possible */
                    186: (function(i) {
                    187:   var u =navigator.userAgent;
                    188:   var e=/*@cc_on!@*/false;
                    189:   var st = setTimeout;
                    190:   if(/webkit/i.test(u)) {
                    191:     st(function() {
                    192:         var dr=document.readyState;
                    193:         if(dr=="loaded" || dr=="complete") {
                    194:           i()
                    195:         }
                    196:         else {
                    197:           st(arguments.callee,10);
                    198:         }
                    199:       },10
                    200:     );
                    201:   }
                    202:   else if((/mozilla/i.test(u) && !/(compati)/.test(u)) || (/opera/i.test(u))) {
                    203:     document.addEventListener("DOMContentLoaded",i,false);
                    204:   } else if(e) {
                    205:     (function() {
                    206:       var t=document.createElement('doc:rdy');
                    207:       try{
                    208:         t.doScroll('left');
                    209:         i();
                    210:         t=null;
                    211:       }
                    212:       catch(e) {
                    213:         st(arguments.callee,0);
                    214:       }
                    215:     })();
                    216:   }
                    217:   else{
                    218:     window.onload=i;
                    219:   }}
                    220: )(generated_toc.init);

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.