/
bobt.js
98 lines (81 loc) · 3.4 KB
/
bobt.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
var bobt = {
makeHeadingName: function(it)
{
var words = it.split(' ');
var name = words.join('');
/* if we've used this heading before, make it unique */
if (typeof(this.headingMap[name]) != 'undefined')
name = name.concat('-' + this.headingSeq++);
/* remember this name is used */
this.headingMap[name] = true;
return name;
},
doSection: function(tocParent, parentSection, depth)
{
var allSections = parentSection.getElementsByClassName('bobt-section');
for(var sectionIndex in allSections)
{
var section = allSections[sectionIndex];
/*
getElementsByClassName() returns all descendants; we only want
the direct descendants, because we will do this recursively for
each one to maintain the toc structure in parallel.
*/
if (section.parentNode != parentSection)
continue;
/* find the span that has the heading */
var allTitles = section.getElementsByClassName('bobt-title');
if (typeof(allTitles[0]) != 'undefined')
{
var bobtTitle = allTitles[0];
/* we only want to see the immediate descendants */
if (bobtTitle.parentNode != section)
continue;
/* create the heading that will replace the span */
var headingA = document.createElement('a');
var headingName = this.makeHeadingName(bobtTitle.innerText);
headingA.setAttribute('id', headingName);
headingA.innerHTML = bobtTitle.innerHTML;
var sectionHeading = document.createElement('h' + depth);
sectionHeading.appendChild(headingA);
/* replace the span with the named heading */
section.insertBefore(sectionHeading, bobtTitle);
section.removeChild(bobtTitle);
/* create the table of contents link */
var tocLiA = document.createElement('a');
tocLiA.setAttribute('href', '#' + headingName);
tocLiA.innerHTML = headingA.innerHTML;
/* add reference to the toc */
var tocLi = document.createElement('li');
tocLi.appendChild(tocLiA);
tocParent.appendChild(tocLi);
/* do the child sections below this */
var childUl = document.createElement('ul');
this.doSection(childUl, section, depth + 1);
if (childUl.childElementCount > 0)
tocLi.appendChild(childUl);
}
}
},
doHeaders: function()
{
/* we need a sequence number for any duplicate headings */
this.headingSeq = 0;
/* we detect duplicate headings using this as a hash */
this.headingMap = {};
/* find the toc, if there is one */
var toc = document.getElementById('bobt-toc');
var tocUl = document.createElement('ul');
if ((typeof(toc) != 'undefined') && (toc.nodeName == 'DIV'))
{
toc.appendChild(tocUl);
toc.appendChild(document.createElement('hr'));
}
/* find and set all the section titles */
this.doSection(tocUl, document.body, 2);
},
doLoad: function()
{
this.doHeaders();
}
}