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