godocs.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // Except as noted, this content is licensed under Creative Commons
  2. // Attribution 3.0
  3. /* A little code to ease navigation of these documents.
  4. *
  5. * On window load we:
  6. * + Generate a table of contents (godocs_generateTOC)
  7. * + Add links up to the top of the doc from each section (godocs_addTopLinks)
  8. */
  9. /* We want to do some stuff on page load (after the HTML is rendered).
  10. So listen for that:
  11. */
  12. function bindEvent(el, e, fn) {
  13. if (el.addEventListener){
  14. el.addEventListener(e, fn, false);
  15. } else if (el.attachEvent){
  16. el.attachEvent('on'+e, fn);
  17. }
  18. }
  19. bindEvent(window, 'load', godocs_onload);
  20. function godocs_onload() {
  21. godocs_bindSearchEvents();
  22. godocs_generateTOC();
  23. godocs_addTopLinks();
  24. }
  25. function godocs_bindSearchEvents() {
  26. var search = document.getElementById('search');
  27. if (!search) {
  28. // no search box (index disabled)
  29. return;
  30. }
  31. function clearInactive() {
  32. if (search.className == "inactive") {
  33. search.value = "";
  34. search.className = "";
  35. }
  36. }
  37. function restoreInactive() {
  38. if (search.value != "") {
  39. return;
  40. }
  41. if (search.type != "search") {
  42. search.value = search.getAttribute("placeholder");
  43. }
  44. search.className = "inactive";
  45. }
  46. restoreInactive();
  47. bindEvent(search, 'focus', clearInactive);
  48. bindEvent(search, 'blur', restoreInactive);
  49. }
  50. /* Generates a table of contents: looks for h2 and h3 elements and generates
  51. * links. "Decorates" the element with id=="nav" with this table of contents.
  52. */
  53. function godocs_generateTOC() {
  54. var navbar = document.getElementById('nav');
  55. if (!navbar) { return; }
  56. var toc_items = [];
  57. var i;
  58. for (i = 0; i < navbar.parentNode.childNodes.length; i++) {
  59. var node = navbar.parentNode.childNodes[i];
  60. if ((node.tagName == 'h2') || (node.tagName == 'H2')) {
  61. if (!node.id) {
  62. node.id = 'tmp_' + i;
  63. }
  64. var text = godocs_nodeToText(node);
  65. if (!text) { continue; }
  66. var textNode = document.createTextNode(text);
  67. var link = document.createElement('a');
  68. link.href = '#' + node.id;
  69. link.appendChild(textNode);
  70. // Then create the item itself
  71. var item = document.createElement('dt');
  72. item.appendChild(link);
  73. toc_items.push(item);
  74. }
  75. if ((node.tagName == 'h3') || (node.tagName == 'H3')) {
  76. if (!node.id) {
  77. node.id = 'tmp_' + i;
  78. }
  79. var text = godocs_nodeToText(node);
  80. if (!text) { continue; }
  81. var textNode = document.createTextNode(text);
  82. var link = document.createElement('a');
  83. link.href = '#' + node.id;
  84. link.appendChild(textNode);
  85. // Then create the item itself
  86. var item = document.createElement('dd');
  87. item.appendChild(link);
  88. toc_items.push(item);
  89. }
  90. }
  91. if (toc_items.length <= 1) { return; }
  92. var dl1 = document.createElement('dl');
  93. var dl2 = document.createElement('dl');
  94. var split_index = (toc_items.length / 2) + 1;
  95. if (split_index < 8) {
  96. split_index = toc_items.length;
  97. }
  98. for (i = 0; i < split_index; i++) {
  99. dl1.appendChild(toc_items[i]);
  100. }
  101. for (/* keep using i */; i < toc_items.length; i++) {
  102. dl2.appendChild(toc_items[i]);
  103. }
  104. var tocTable = document.createElement('table');
  105. navbar.appendChild(tocTable);
  106. tocTable.className = 'unruled';
  107. var tocBody = document.createElement('tbody');
  108. tocTable.appendChild(tocBody);
  109. var tocRow = document.createElement('tr');
  110. tocBody.appendChild(tocRow);
  111. // 1st column
  112. var tocCell = document.createElement('td');
  113. tocCell.className = 'first';
  114. tocRow.appendChild(tocCell);
  115. tocCell.appendChild(dl1);
  116. // 2nd column
  117. tocCell = document.createElement('td');
  118. tocRow.appendChild(tocCell);
  119. tocCell.appendChild(dl2);
  120. }
  121. /* Returns the "This sweet header" from <h2>This <i>sweet</i> header</h2>.
  122. * Takes a node, returns a string.
  123. */
  124. function godocs_nodeToText(node) {
  125. var TEXT_NODE = 3; // Defined in Mozilla but not MSIE :(
  126. var text = '';
  127. for (var j = 0; j != node.childNodes.length; j++) {
  128. var child = node.childNodes[j];
  129. if (child.nodeType == TEXT_NODE) {
  130. if (child.nodeValue != '[Top]') { //ok, that's a hack, but it works.
  131. text = text + child.nodeValue;
  132. }
  133. } else {
  134. text = text + godocs_nodeToText(child);
  135. }
  136. }
  137. return text;
  138. }
  139. /* For each H2 heading, add a link up to the #top of the document.
  140. * (As part of this: ensure existence of 'top' named anchor link
  141. * (theoretically at doc's top).)
  142. */
  143. function godocs_addTopLinks() {
  144. /* Make sure there's a "top" to link to. */
  145. var top = document.getElementById('top');
  146. if (!top) {
  147. document.body.id = 'top';
  148. }
  149. if (!document.getElementsByTagName) return; // no browser support
  150. var headers = document.getElementsByTagName('h2');
  151. for (var i = 0; i < headers.length; i++) {
  152. var span = document.createElement('span');
  153. span.className = 'navtop';
  154. var link = document.createElement('a');
  155. span.appendChild(link);
  156. link.href = '#top';
  157. var textNode = document.createTextNode('[Top]');
  158. link.appendChild(textNode);
  159. headers[i].appendChild(span);
  160. }
  161. }