extra.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. // good tests: file.md,
  39. var href = func.replace(/[\.:\(\)]/g, '').replace(/ --|, | /g, '-');
  40. var link = '<a href="#' + href.toLowerCase() + '">' + func + '</a>';
  41. return '<tr><td>' + link + '</td><td>' + intro + '</td></tr>';
  42. }
  43. }
  44. function hideNavigationForAllButSelectedLanguage() {
  45. var selectedLanguageCode = determineSelectedLanguageCode();
  46. var selectedLanguageName = languageCodeToNameMap[selectedLanguageCode];
  47. // Finds all subnav elements and hides them if they're /language/ subnavs. Hence, all 'Modules' subnav elements
  48. // won't be hidden.
  49. // <ul class="subnav">
  50. // <li><span>Modules</span></li>
  51. // <li class="toctree-l1 ">
  52. // <a class="" href="EN/modules/node/">node</a>
  53. // </li>
  54. $('.subnav li span').not(':contains(' + selectedLanguageName + ')').each(function (index) {
  55. var spanElement = $(this);
  56. if ($.inArray(spanElement.text(), languageNames) > -1) {
  57. spanElement.parent().parent().hide();
  58. }
  59. });
  60. }
  61. /**
  62. * Adds a language selector to the RTD fly-out menu found bottom left. Example:
  63. *
  64. * <dl>
  65. * <dt>Languages</dt>
  66. * <dd><a href="http://nodemcu.readthedocs.io/en/<branch>/de/">de</a></dd>
  67. * <strong>
  68. * <dd><a href="http://nodemcu.readthedocs.io/en/<branch>/en/">en</a></dd>
  69. * </strong>
  70. * </dl>
  71. *
  72. * UGLY! That fly-out menu is added by RTD with an AJAX call after page load. Hence, we need to
  73. * react to the subsequent DOM manipulation using a DOM4 MutationObserver. The provided structure
  74. * is as follows:
  75. *
  76. * <div class="rst-other-versions">
  77. * <!-- Inserted RTD Footer -->
  78. * <div class="injected">
  79. */
  80. function addLanguageSelectorToRtdFlyOutMenu() {
  81. var flyOutWrapper = $('.rst-other-versions');
  82. // only relevant on RTD
  83. if (flyOutWrapper.size() > 0) {
  84. var observer = new MutationObserver(function (mutations) {
  85. // since mutation on the target node was triggered we can safely assume the injected RTD div has now been added
  86. var injectedDiv = $('.rst-other-versions .injected');
  87. var selectedLanguageCode = determineSelectedLanguageCode();
  88. var dl = document.createElement('dl');
  89. var dt = document.createElement('dt');
  90. dl.appendChild(dt);
  91. dt.appendChild(document.createTextNode('Languages'));
  92. for (var languageCode in languageCodeToNameMap) {
  93. dl.appendChild(createLanguageLinkFor(languageCode, selectedLanguageCode === languageCode));
  94. }
  95. injectedDiv.prepend(dl);
  96. // no need for that observer anymore
  97. observer.disconnect();
  98. });
  99. // observed target node is the fly-out wrapper, the only event we care about is when children are modified
  100. observer.observe(flyOutWrapper[0], {childList: true});
  101. }
  102. }
  103. /**
  104. * The module doc pages contain relative links to artifacts in the GitHub repository. For those links to work both
  105. * on GitHub (i.e. when the page is viewed on GitHub) and on RTD they are defined with a relative URL. This function
  106. * replaces the relative path with an absolute path based on the selected branch.
  107. */
  108. function replaceRelativeLinksWithStaticGitHubUrl() {
  109. var relativePath = isOnRtd() ? "../../../.." : "../../..";
  110. var gitHubPath = "https://github.com/nodemcu/nodemcu-firmware/tree/" + determineSelectedBranch();
  111. var gitHubLinks = $("a[href^='" + relativePath + "']").each(function (index) {
  112. var url = $(this).attr('href');
  113. $(this).attr('href', url.replace(relativePath, gitHubPath));
  114. });
  115. }
  116. function createLanguageLinkFor(languageCode, isCurrentlySelected) {
  117. var strong;
  118. // split[0] is an '' because the path starts with the separator
  119. var pathSegments = window.location.pathname.split('/');
  120. var dd = document.createElement("dd");
  121. var href = document.createElement("a");
  122. href.setAttribute('href', '/' + pathSegments[1] + '/' + pathSegments[2] + '/' + languageCode);
  123. href.appendChild(document.createTextNode(languageCode));
  124. dd.appendChild(href);
  125. if (isCurrentlySelected) {
  126. strong = document.createElement("strong");
  127. strong.appendChild(dd);
  128. return strong;
  129. } else {
  130. return dd;
  131. }
  132. }
  133. /**
  134. * Analyzes the URL of the current page to find out what the selected language is. It's usually
  135. * part of the location path. The code needs to distinguish between running MkDocs standalone
  136. * and docs served from RTD. If no valid language could be determined the default language is
  137. * returned.
  138. *
  139. * @returns 2-char language code
  140. */
  141. function determineSelectedLanguageCode() {
  142. var selectedLanguageCode, path = window.location.pathname;
  143. if (isOnRtd()) {
  144. // path is like /en/<branch>/<lang>/build/ -> extract 'lang'
  145. // split[0] is an '' because the path starts with the separator
  146. selectedLanguageCode = path.split('/')[3];
  147. } else if (!window.location.href.startsWith('file://')) {
  148. // path is like /<lang>/build/ -> extract 'lang'
  149. selectedLanguageCode = path.substr(1, 2);
  150. }
  151. if (!selectedLanguageCode || selectedLanguageCode.length > 2) {
  152. selectedLanguageCode = defaultLanguageCode;
  153. }
  154. return selectedLanguageCode;
  155. }
  156. /**
  157. * Analyzes the URL of the current page to find out what the selected GitHub branch is. It's usually
  158. * part of the location path. The code needs to distinguish between running MkDocs standalone
  159. * and docs served from RTD. If no valid branch could be determined 'dev' returned.
  160. *
  161. * @returns GitHub branch name
  162. */
  163. function determineSelectedBranch() {
  164. var branch = 'dev', path = window.location.pathname;
  165. if (isOnRtd()) {
  166. // path is like /en/<branch>/<lang>/build/ -> extract 'lang'
  167. // split[0] is an '' because the path starts with the separator
  168. var thirdPathSegment = path.split('/')[2];
  169. // 'latest' is an alias on RTD for the 'dev' branch - which is the default for 'branch' here
  170. if (thirdPathSegment != 'latest') {
  171. branch = thirdPathSegment;
  172. }
  173. }
  174. return branch;
  175. }
  176. function values(associativeArray) {
  177. var values = [];
  178. for (var key in associativeArray) {
  179. if (associativeArray.hasOwnProperty(key)) {
  180. values.push(associativeArray[key]);
  181. }
  182. }
  183. return values;
  184. }
  185. function isOnRtd() {
  186. return window.location.origin.indexOf('readthedocs') > -1;
  187. }
  188. }());