223 lines
8.7 KiB
JavaScript
223 lines
8.7 KiB
JavaScript
var nodemcu = nodemcu || {};
|
|
(function () {
|
|
'use strict';
|
|
//var languageCodeToNameMap = {en: 'English', de: 'Deutsch'};
|
|
var languageCodeToNameMap = {en: 'English'};
|
|
var languageNames = values(languageCodeToNameMap);
|
|
var defaultLanguageCode = 'en';
|
|
|
|
$(document).ready(function () {
|
|
addToc();
|
|
fixSearch();
|
|
hideNavigationForAllButSelectedLanguage();
|
|
addLanguageSelectorToRtdFlyOutMenu();
|
|
replaceRelativeLinksWithStaticGitHubUrl();
|
|
});
|
|
|
|
/**
|
|
* Adds a TOC-style table to each page in the 'Modules' section.
|
|
*/
|
|
function addToc() {
|
|
var func, intro, tocHtmlTable;
|
|
if (isModulePage()) {
|
|
tocHtmlTable = '<table class="docutils">';
|
|
$('h2').each(function (index) {
|
|
// 'slice' cuts off the single permalink character at the end of the text (e.g. '¶')
|
|
func = $(this).text().slice(0, -1);
|
|
// get the first sentence of the paragraph directly below h2
|
|
intro = $(this).next().text();
|
|
intro = intro.substring(0, intro.indexOf('.') + 1);
|
|
tocHtmlTable += createTocTableRow(func, intro);
|
|
});
|
|
tocHtmlTable += '</table>';
|
|
$(tocHtmlTable).insertBefore($('h2').first())
|
|
}
|
|
function isModulePage() {
|
|
// if the breadcrumb contains 'Modules »' it must be an API page
|
|
return $("ul.wy-breadcrumbs li:contains('Modules »')").size() > 0;
|
|
}
|
|
function createTocTableRow(func, intro) {
|
|
// fragile attempt to auto-create the in-page anchor
|
|
var href = func.replace(/\.|:/g, '').replace('()', '').replace(' --', '-').replace(/ /g, '-');
|
|
var link = '<a href="#' + href.toLowerCase() + '">' + func + '</a>';
|
|
return '<tr><td>' + link + '</td><td>' + intro + '</td></tr>';
|
|
}
|
|
}
|
|
|
|
/*
|
|
* RTD messes up MkDocs' search feature by tinkering with the search box defined in the theme, see
|
|
* https://github.com/rtfd/readthedocs.org/issues/1088. This function sets up a DOM4 MutationObserver
|
|
* to react to changes to the search form (triggered by RTD on doc ready). It then reverts everything
|
|
* the RTD JS code modified.
|
|
*/
|
|
function fixSearch() {
|
|
var target = document.getElementById('rtd-search-form');
|
|
var config = {attributes: true, childList: true};
|
|
|
|
var observer = new MutationObserver(function(mutations) {
|
|
// if it isn't disconnected it'll loop infinitely because the observed element is modified
|
|
observer.disconnect();
|
|
var form = $('#rtd-search-form');
|
|
form.empty();
|
|
form.attr('action', 'https://' + window.location.hostname + '/en/' + determineSelectedBranch() + '/search.html');
|
|
$('<input>').attr({
|
|
type: "text",
|
|
name: "q",
|
|
placeholder: "Search docs"
|
|
}).appendTo(form);
|
|
});
|
|
|
|
if (window.location.origin.indexOf('readthedocs') > -1) {
|
|
observer.observe(target, config);
|
|
}
|
|
}
|
|
|
|
function hideNavigationForAllButSelectedLanguage() {
|
|
var selectedLanguageCode = determineSelectedLanguageCode();
|
|
var selectedLanguageName = languageCodeToNameMap[selectedLanguageCode];
|
|
// Finds all subnav elements and hides them if they're /language/ subnavs. Hence, all 'Modules' subnav elements
|
|
// won't be hidden.
|
|
// <ul class="subnav">
|
|
// <li><span>Modules</span></li>
|
|
// <li class="toctree-l1 ">
|
|
// <a class="" href="EN/modules/node/">node</a>
|
|
// </li>
|
|
$('.subnav li span').not(':contains(' + selectedLanguageName + ')').each(function (index) {
|
|
var spanElement = $(this);
|
|
if ($.inArray(spanElement.text(), languageNames) > -1) {
|
|
spanElement.parent().parent().hide();
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Adds a language selector to the RTD fly-out menu found bottom left. Example:
|
|
*
|
|
* <dl>
|
|
* <dt>Languages</dt>
|
|
* <dd><a href="http://nodemcu.readthedocs.io/en/<branch>/de/">de</a></dd>
|
|
* <strong>
|
|
* <dd><a href="http://nodemcu.readthedocs.io/en/<branch>/en/">en</a></dd>
|
|
* </strong>
|
|
* </dl>
|
|
*
|
|
* UGLY! That fly-out menu is added by RTD with an AJAX call after page load. Hence, we need to
|
|
* react to the subsequent DOM manipulation using a DOM4 MutationObserver. The provided structure
|
|
* is as follows:
|
|
*
|
|
* <div class="rst-other-versions">
|
|
* <!-- Inserted RTD Footer -->
|
|
* <div class="injected">
|
|
*/
|
|
function addLanguageSelectorToRtdFlyOutMenu() {
|
|
var flyOutWrapper = $('.rst-other-versions');
|
|
// only relevant on RTD
|
|
if (flyOutWrapper.size() > 0) {
|
|
var observer = new MutationObserver(function (mutations) {
|
|
// since mutation on the target node was triggered we can safely assume the injected RTD div has now been added
|
|
var injectedDiv = $('.rst-other-versions .injected');
|
|
var selectedLanguageCode = determineSelectedLanguageCode();
|
|
var dl = document.createElement('dl');
|
|
var dt = document.createElement('dt');
|
|
dl.appendChild(dt);
|
|
dt.appendChild(document.createTextNode('Languages'));
|
|
for (var languageCode in languageCodeToNameMap) {
|
|
dl.appendChild(createLanguageLinkFor(languageCode, selectedLanguageCode === languageCode));
|
|
}
|
|
injectedDiv.prepend(dl);
|
|
// no need for that observer anymore
|
|
observer.disconnect();
|
|
});
|
|
|
|
// observed target node is the fly-out wrapper, the only event we care about is when children are modified
|
|
observer.observe(flyOutWrapper[0], {childList: true});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The module doc pages contain relative links to artifacts in the GitHub repository. For those links to work both
|
|
* on GitHub (i.e. when the page is viewed on GitHub) and on RTD they are defined with a relative URL. This function
|
|
* replaces the relative path with an absolute path based on the selected branch.
|
|
*/
|
|
function replaceRelativeLinksWithStaticGitHubUrl() {
|
|
var relativePath = "../../../..";
|
|
var gitHubPath = "https://github.com/nodemcu/nodemcu-firmware/tree/" + determineSelectedBranch();
|
|
var gitHubLinks = $("a[href^='" + relativePath + "']").each(function (index) {
|
|
var url = $(this).attr('href');
|
|
$(this).attr('href', url.replace(relativePath, gitHubPath));
|
|
});
|
|
}
|
|
|
|
function createLanguageLinkFor(languageCode, isCurrentlySelected) {
|
|
var strong;
|
|
// split[0] is an '' because the path starts with the separator
|
|
var pathSegments = window.location.pathname.split('/');
|
|
var dd = document.createElement("dd");
|
|
var href = document.createElement("a");
|
|
href.setAttribute('href', '/' + pathSegments[1] + '/' + pathSegments[2] + '/' + languageCode);
|
|
href.appendChild(document.createTextNode(languageCode));
|
|
dd.appendChild(href);
|
|
if (isCurrentlySelected) {
|
|
strong = document.createElement("strong");
|
|
strong.appendChild(dd);
|
|
return strong;
|
|
} else {
|
|
return dd;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Analyzes the URL of the current page to find out what the selected language is. It's usually
|
|
* part of the location path. The code needs to distinguish between running MkDocs standalone
|
|
* and docs served from RTD. If no valid language could be determined the default language is
|
|
* returned.
|
|
*
|
|
* @returns 2-char language code
|
|
*/
|
|
function determineSelectedLanguageCode() {
|
|
var selectedLanguageCode, path = window.location.pathname;
|
|
if (window.location.origin.indexOf('readthedocs') > -1) {
|
|
// path is like /en/<branch>/<lang>/build/ -> extract 'lang'
|
|
// split[0] is an '' because the path starts with the separator
|
|
selectedLanguageCode = path.split('/')[3];
|
|
} else {
|
|
// path is like /<lang>/build/ -> extract 'lang'
|
|
selectedLanguageCode = path.substr(1, 2);
|
|
}
|
|
if (!selectedLanguageCode || selectedLanguageCode.length > 2) {
|
|
selectedLanguageCode = defaultLanguageCode;
|
|
}
|
|
return selectedLanguageCode;
|
|
}
|
|
|
|
/**
|
|
* Analyzes the URL of the current page to find out what the selected GitHub branch is. It's usually
|
|
* part of the location path. The code needs to distinguish between running MkDocs standalone
|
|
* and docs served from RTD. If no valid branch could be determined 'dev' returned.
|
|
*
|
|
* @returns GitHub branch name
|
|
*/
|
|
function determineSelectedBranch() {
|
|
var branch = 'dev', path = window.location.pathname;
|
|
if (window.location.origin.indexOf('readthedocs') > -1) {
|
|
// path is like /en/<branch>/<lang>/build/ -> extract 'lang'
|
|
// split[0] is an '' because the path starts with the separator
|
|
var thirdPathSegment = path.split('/')[2];
|
|
// 'latest' is an alias on RTD for the 'dev' branch - which is the default for 'branch' here
|
|
if (thirdPathSegment != 'latest') {
|
|
branch = thirdPathSegment;
|
|
}
|
|
}
|
|
return branch;
|
|
}
|
|
|
|
function values(associativeArray) {
|
|
var values = [];
|
|
for (var key in associativeArray) {
|
|
if (associativeArray.hasOwnProperty(key)) {
|
|
values.push(associativeArray[key]);
|
|
}
|
|
}
|
|
return values;
|
|
}
|
|
}()); |