blob: accb7796806de41aa0564d60136134afaea53c50 [file] [log] [blame]
Brian Silverman1a675112016-02-20 20:42:49 -05001TocTypeEnum = {
2 VERTICAL: 1,
3 HORIZONTAL: 2
4};
5
6function CreateTOC(tocElement) {
7
8 // Find the toc element DIV. We'll place our TOC there.
9 var toc = document.getElementById(tocElement);
10
11 var tocTypeClass = toc.className;
12 var tocType;
13
14 switch (tocTypeClass) {
15 case 'horizontal_toc':
16 tocType = TocTypeEnum.HORIZONTAL;
17 break;
18 case 'vertical_toc':
19 tocType = TocTypeEnum.VERTICAL;
20 break;
21 default:
22 tocType = TocTypeEnum.VERTICAL;
23 break;
24 }
25
26 // If toc_levels is defined, set headingLevels to it.
27 // Otherwise, use default value of "h2,h3"
28 var headingLevels;
29 if (typeof toc_levels === 'undefined') {
30 headingLevels = 'h2,h3';
31 } else {
32
33 }
34
35 // Collect all section heading elements in an array
36 var headings = document.querySelectorAll(headingLevels);
37
38 // Add TOC title elements
39 var tocHeadingDiv = document.createElement('div');
40 toc.appendChild(tocHeadingDiv);
41 tocHeadingDiv.className = 'toc_title';
42 var tocHeading = document.createElement('h3');
43 toc.appendChild(tocHeading);
44 tocHeading.className = 'ignoreLink';
45 tocHeading.id = 'toc';
46 var tocText = document.createTextNode('Table of Contents');
47 tocHeading.appendChild(tocText);
48
49 // Add table and tbody
50 var tocTable = document.createElement('table');
51 if (tocType == TocTypeEnum.VERTICAL) {
52 tocTable.className = 'columns';
53 }
54 toc.appendChild(tocTable);
55
56 var tbody_element = document.createElement('tbody');
57 tbody_element.setAttribute('valign', 'top');
58 tbody_element.className = 'toc';
59 tocTable.appendChild(tbody_element);
60
61 // Get the highest level heading
62 var firstHeading = headings[0];
63 var masterLevel = parseInt(headingLevels.charAt(1));
64
65 // Get the lowest heading level
66 var lowestLevel = parseInt(headingLevels.charAt(headingLevels - 1));
67
68 switch (tocType) {
69 case TocTypeEnum.HORIZONTAL:
70 CreateHorizontalTOC(headings, masterLevel, lowestLevel, tbody_element);
71 break;
72 case TocTypeEnum.VERTICAL:
73 CreateVerticalTOC(headings, masterLevel, lowestLevel, tbody_element);
74 break;
75 default:
76 }
77}
78
79function CreateHorizontalTOC(
80 headings, masterLevel, lowestLevel, tbody_element) {
81
82 // Initialize the header counter
83 var h = 0;
84 var ignoreChildren = false;
85
86 while (h < headings.length) {
87 // Get current heading
88 var heading = headings[h];
89
90 // Get the current heading level
91 var level = parseInt(heading.tagName.charAt(1));
92
93 if (isNaN(level) || level < 1 || level > lowestLevel) continue;
94
95 // If level is a masterLevel, make it a TOC parent category
96 if ((level == masterLevel) && (!hasClass(heading, 'ignoreLink'))) {
97 toc_current_row = AddTOCMaster(tbody_element, heading);
98 ignoreChildren = false;
99 }
100
101 if ((level == masterLevel) && (hasClass(heading, 'ignoreLink'))) {
102 ignoreChildren = true;
103 }
104
105 if ((level != masterLevel) && (!ignoreChildren)) {
106 AddTOCElements(toc_current_row, heading);
107 }
108
109 // Advance the header counter
110 h++;
111 }
112}
113
114// Adds a master Table of Content heading
115function AddTOCMaster(tocTable, heading) {
116
117 // Add the table row scaffolding
118 var toc_tr = document.createElement('tr');
119 tocTable.appendChild(toc_tr);
120 toc_tr.setAttribute('valign', 'top');
121 var toc_tr_td = document.createElement('td');
122 toc_tr.appendChild(toc_tr_td);
123 var toc_category = document.createElement('div');
124 toc_tr_td.appendChild(toc_category);
125 toc_category.className = 'toc_category';
126
127 // Create the link to this header
128 var link = document.createElement('a');
129 link.href = '#' + heading.id; // Create the anchor link
130 link.textContent = heading.textContent; // Link text is same as heading
131 toc_category.appendChild(link);
132
133 // Add the container table cell for its children
134 var toc_td = document.createElement('td');
135 toc_tr.appendChild(toc_td);
136 var toc_td_div = document.createElement('div');
137 toc_td_div.className = 'toc_stylepoint';
138 toc_td.appendChild(toc_td_div);
139
140 return (toc_td_div);
141}
142
143// Adds Table of Contents element to a master heading as children
144function AddTOCElements(toc_div, heading) {
145
146 if (heading.offsetParent === null) {
147 // The element is currently hidden, so don't create a TOC entry
148 } else {
149 // Create the list item element
150 var toc_list_element = document.createElement('li');
151 toc_list_element.className = 'toc_entry';
152 toc_div.appendChild(toc_list_element);
153
154 // Create the link to this header
155 var link = document.createElement('a');
156 link.href = '#' + heading.id; // Create the anchor link
157 link.textContent = heading.textContent; // Link text is same as heading
158 toc_list_element.appendChild(link);
159 }
160}
161
162function CreateVerticalTOC(headings, masterLevel, lowestLevel, tbody_element) {
163
164 // Create the Column scaffolding
165 var toc_tr = document.createElement('tr');
166 tbody_element.appendChild(toc_tr);
167 var toc_tr_td = document.createElement('td');
168 toc_tr_td.className = 'two_columns';
169 toc_tr.appendChild(toc_tr_td);
170
171
172 // Initialize the header counter and the current row
173 var h = 0;
174 var toc_current_col = null;
175 var ignoreChildren = false;
176
177 while (h < headings.length) {
178 // Get current heading
179 var heading = headings[h];
180
181 // Get the current heading level
182 var level = parseInt(heading.tagName.charAt(1));
183
184 if (isNaN(level) || level < 1 || level > lowestLevel) continue;
185
186 // If level is a masterLevel, make it a TOC parent category
187 if ((level == masterLevel) && (!hasClass(heading, 'ignoreLink'))) {
188 if (heading.offsetParent === null) {
189 // The element is currently hidden, so don't create a TOC entry
190 } else {
191 var td_dl = document.createElement('dl');
192 toc_tr_td.appendChild(td_dl);
193 var td_dt = document.createElement('dt');
194 td_dl.appendChild(td_dt);
195 toc_current_col = td_dl;
196
197 // Create the link to this header
198 var link = document.createElement('a');
199 link.href = '#' + heading.id; // Create the anchor link
200 link.textContent = heading.textContent; // Link text is same as heading
201 td_dt.appendChild(link);
202 ignoreChildren = false;
203 }
204 }
205
206 // If level is a masterLevel but it's specified to ignore links, skip it
207 // and its children.
208 if ((level == masterLevel) && (hasClass(heading, 'ignoreLink'))) {
209 ignoreChildren = true;
210 }
211
212 if ((level != masterLevel) && (!ignoreChildren)) {
213 if (heading.offsetParent === null) {
214 // The element is currently hidden, so don't create a TOC entry
215 } else {
216 var td_dd = document.createElement('dd');
217 toc_current_col.appendChild(td_dd);
218 // Create the link to this header
219 var link = document.createElement('a');
220 link.href = '#' + heading.id; // Create the anchor link
221 link.textContent = heading.textContent; // Link text is same as heading
222 td_dd.appendChild(link);
223 }
224 }
225
226 // Advance the header counter
227 h++;
228 }
229}
230
231/*
232 * Utility function for finding elements with a given
233 * class.
234 */
235function hasClass(element, cls) {
236 return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
237}
238
239/*
240 * Linkify all h2 through h4 headers, except for those marked
241 * "ignoreLink"
242 */
243
244// Add the link image to the element.
245function LinkifyHeader(header, fileName, sizePixels) {
246 var link = document.createElement('a');
247 link.href = '#' + header.id;
248 link.alt = 'link to ' + header.id;
249 link.innerHTML =
250 '<img src="include/' + fileName + '"' +
251 ' width=' + sizePixels +
252 ' height=' + sizePixels +
253 ' style="float:left;position:relative;bottom:5px;">';
254 header.appendChild(link);
255}
256
257// Find all elements of the given tag and linkify if
258// they don't have 'ignoreLink' in their class.
259function LinkifyHeadersForTag(tagName) {
260 var headers = document.getElementsByTagName(tagName);
261 var header;
262 for (var j = 0; j != headers.length; j++) {
263 header = headers[j];
264 if (!hasClass(header, 'ignoreLink') && ('id' in header)) {
265 if (header.id != '') {
266 LinkifyHeader(header, 'link.png', 21);
267 header.style.left = '-46px';
268 header.style.position = 'relative';
269 }
270 }
271 }
272}
273
274// Linkify all h2, h3, and h4s. h1s are titles.
275function LinkifyHeaders() {
276 LinkifyHeadersForTag('h2');
277 LinkifyHeadersForTag('h3');
278 LinkifyHeadersForTag('h4');
279}
280
281/*
282 * Initialize the style guide by showing all internal
283 * elements and then linkifying the headers.
284 */
285
286function initStyleGuide() {
287 LinkifyHeaders();
288 CreateTOC('tocDiv');
289}