extra.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. var nodemcu = nodemcu || {};
  2. (function () {
  3. 'use strict';
  4. //var languageCodeToNameMap = {en: 'English', de: 'Deutsch'};
  5. var languageCodeToNameMap = {en: 'English'};
  6. var languageNames = values(languageCodeToNameMap);
  7. var defaultLanguageCode = 'en';
  8. $(document).ready(function () {
  9. addToc();
  10. hideNavigationForAllButSelectedLanguage();
  11. addLanguageSelectorToRtdFlyOutMenu();
  12. replaceRelativeLinksWithStaticGitHubUrl();
  13. });
  14. /**
  15. * Adds a TOC-style table to each page in the 'Modules' section.
  16. */
  17. function addToc() {
  18. var func, intro, tocHtmlTable;
  19. if (isModulePage()) {
  20. tocHtmlTable = '<table class="docutils">';
  21. $('h2').each(function (index) {
  22. // 'slice' cuts off the single permalink character at the end of the text (e.g. '¶')
  23. func = $(this).text().slice(0, -1);
  24. // get the first sentence of the paragraph directly below h2
  25. intro = $(this).next().text();
  26. intro = intro.substring(0, intro.indexOf('.') + 1);
  27. tocHtmlTable += createTocTableRow(func, intro);
  28. });
  29. tocHtmlTable += '</table>';
  30. $(tocHtmlTable).insertBefore($('h2').first())
  31. }
  32. function isModulePage() {
  33. // if the breadcrumb contains 'Modules »' it must be an API page
  34. return $("ul.wy-breadcrumbs li:contains('Modules »')").size() > 0;
  35. }
  36. function createTocTableRow(func, intro) {
  37. // fragile attempt to auto-create the in-page anchor
  38. var href = func.replace(/\.|:/g, '').replace('()', '').replace(' --', '-').replace(/ /g, '-');
  39. var link = '<a href="#' + href.toLowerCase() + '">' + func + '</a>';
  40. return '<tr><td>' + link + '</td><td>' + intro + '</td></tr>';
  41. }
  42. }
  43. function hideNavigationForAllButSelectedLanguage() {
  44. var selectedLanguageCode = determineSelectedLanguageCode();
  45. var selectedLanguageName = languageCodeToNameMap[selectedLanguageCode];
  46. // Finds all subnav elements and hides them if they're /language/ subnavs. Hence, all 'Modules' subnav elements
  47. // won't be hidden.
  48. // <ul class="subnav">
  49. // <li><span>Modules</span></li>
  50. // <li class="toctree-l1 ">
  51. // <a class="" href="EN/modules/node/">node</a>
  52. // </li>
  53. $('.subnav li span').not(':contains(' + selectedLanguageName + ')').each(function (index) {
  54. var spanElement = $(this);
  55. if ($.inArray(spanElement.text(), languageNames) > -1) {
  56. spanElement.parent().parent().hide();
  57. }
  58. });
  59. }
  60. /**
  61. * Adds a language selector to the RTD fly-out menu found bottom left. Example:
  62. *
  63. * <dl>
  64. * <dt>Languages</dt>
  65. * <dd><a href="http://nodemcu.readthedocs.org/en/<branch>/de/">de</a></dd>
  66. * <strong>
  67. * <dd><a href="http://nodemcu.readthedocs.org/en/<branch>/en/">en</a></dd>
  68. * </strong>
  69. * </dl>
  70. *
  71. * UGLY! That fly-out menu is added by RTD with an AJAX call after page load. Hence, we need to
  72. * react to the subsequent DOM manipulation using a DOM4 MutationObserver. The provided structure
  73. * is as follows:
  74. *
  75. * <div class="rst-other-versions">
  76. * <!-- Inserted RTD Footer -->
  77. * <div class="injected">
  78. */
  79. function addLanguageSelectorToRtdFlyOutMenu() {
  80. var flyOutWrapper = $('.rst-other-versions');
  81. // only relevant on RTD
  82. if (flyOutWrapper.size() > 0) {
  83. var observer = new MutationObserver(function (mutations) {
  84. // since mutation on the target node was triggered we can safely assume the injected RTD div has now been added
  85. var injectedDiv = $('.rst-other-versions .injected');
  86. var selectedLanguageCode = determineSelectedLanguageCode();
  87. var dl = document.createElement('dl');
  88. var dt = document.createElement('dt');
  89. dl.appendChild(dt);
  90. dt.appendChild(document.createTextNode('Languages'));
  91. for (var languageCode in languageCodeToNameMap) {
  92. dl.appendChild(createLanguageLinkFor(languageCode, selectedLanguageCode === languageCode));
  93. }
  94. injectedDiv.prepend(dl);
  95. // no need for that observer anymore
  96. observer.disconnect();
  97. });
  98. // observed target node is the fly-out wrapper, the only event we care about is when children are modified
  99. observer.observe(flyOutWrapper[0], {childList: true});
  100. }
  101. }
  102. /**
  103. * The module doc pages contain relative links to artifacts in the GitHub repository. For those links to work both
  104. * on GitHub (i.e. when the page is viewed on GitHub) and on RTD they are defined with a relative URL. This function
  105. * replaces the relative path with an absolute path based on the selected branch.
  106. */
  107. function replaceRelativeLinksWithStaticGitHubUrl() {
  108. var relativePath = "../../../..";
  109. var gitHubPath = "https://github.com/nodemcu/nodemcu-firmware/tree/" + determineSelectedBranch();
  110. var gitHubLinks = $("a[href^='" + relativePath + "']").each(function (index) {
  111. var url = $(this).attr('href');
  112. $(this).attr('href', url.replace(relativePath, gitHubPath));
  113. });
  114. }
  115. function createLanguageLinkFor(languageCode, isCurrentlySelected) {
  116. var strong;
  117. // split[0] is an '' because the path starts with the separator
  118. var pathSegments = window.location.pathname.split('/');
  119. var dd = document.createElement("dd");
  120. var href = document.createElement("a");
  121. href.setAttribute('href', '/' + pathSegments[1] + '/' + pathSegments[2] + '/' + languageCode);
  122. href.appendChild(document.createTextNode(languageCode));
  123. dd.appendChild(href);
  124. if (isCurrentlySelected) {
  125. strong = document.createElement("strong");
  126. strong.appendChild(dd);
  127. return strong;
  128. } else {
  129. return dd;
  130. }
  131. }
  132. /**
  133. * Analyzes the URL of the current page to find out what the selected language is. It's usually
  134. * part of the location path. The code needs to distinguish between running MkDocs standalone
  135. * and docs served from RTD. If no valid language could be determined the default language is
  136. * returned.
  137. *
  138. * @returns 2-char language code
  139. */
  140. function determineSelectedLanguageCode() {
  141. var selectedLanguageCode, path = window.location.pathname;
  142. if (window.location.origin.indexOf('readthedocs') > -1) {
  143. // path is like /en/<branch>/<lang>/build/ -> extract 'lang'
  144. // split[0] is an '' because the path starts with the separator
  145. selectedLanguageCode = path.split('/')[3];
  146. } else {
  147. // path is like /<lang>/build/ -> extract 'lang'
  148. selectedLanguageCode = path.substr(1, 2);
  149. }
  150. if (!selectedLanguageCode || selectedLanguageCode.length > 2) {
  151. selectedLanguageCode = defaultLanguageCode;
  152. }
  153. return selectedLanguageCode;
  154. }
  155. /**
  156. * Analyzes the URL of the current page to find out what the selected GitHub branch is. It's usually
  157. * part of the location path. The code needs to distinguish between running MkDocs standalone
  158. * and docs served from RTD. If no valid branch could be determined 'dev' returned.
  159. *
  160. * @returns GitHub branch name
  161. */
  162. function determineSelectedBranch() {
  163. var branch = 'dev', path = window.location.pathname;
  164. if (window.location.origin.indexOf('readthedocs') > -1) {
  165. // path is like /en/<branch>/<lang>/build/ -> extract 'lang'
  166. // split[0] is an '' because the path starts with the separator
  167. branch = path.split('/')[2];
  168. }
  169. return branch;
  170. }
  171. function values(associativeArray) {
  172. var values = [];
  173. for (var key in associativeArray) {
  174. if (associativeArray.hasOwnProperty(key)) {
  175. values.push(associativeArray[key]);
  176. }
  177. }
  178. return values;
  179. }
  180. }());