extra.js 5.9 KB

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