Inject the flyout

Inject the flyout on its position when on Read the Docs and the user defined
`flyout_display="attached"`.
This commit is contained in:
Manuel Kaufmann 2025-01-16 15:50:32 +01:00
parent 8080625136
commit ca57ae3b2d
2 changed files with 4 additions and 140 deletions

View File

@ -156,8 +156,10 @@
</div>
{%- endblock %}
</div>
{%- block extranavigation %}
{%- endblock %}
{%- if READTHEDOCS and theme_flyout_display == "attached" %}
<readthedocs-flyout position="inline"></readthedocs-flyout>
{%- endif %}
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

View File

@ -1,144 +1,6 @@
const themeFlyoutDisplay = "{{ theme_flyout_display }}";
const themeVersionSelector = {{ 'true' if theme_version_selector|tobool else 'false' }};
const themeLanguageSelector = {{ 'true' if theme_language_selector|tobool else 'false' }};
if (themeFlyoutDisplay === "attached") {
function renderLanguages(config) {
if (!config.projects.translations.length) {
return "";
}
// Insert the current language to the options on the selector
let languages = config.projects.translations.concat(config.projects.current);
languages = languages.sort((a, b) => a.language.name.localeCompare(b.language.name));
const languagesHTML = `
<dl>
<dt>{{ _('Languages') }}</dt>
${languages
.map(
(translation) => `
<dd ${translation.slug == config.projects.current.slug ? 'class="rtd-current-item"' : ""}>
<a href="${translation.urls.documentation}">${translation.language.code}</a>
</dd>
`,
)
.join("\n")}
</dl>
`;
return languagesHTML;
}
function renderVersions(config) {
if (!config.versions.active.length) {
return "";
}
const versionsHTML = `
<dl>
<dt>{{ _('Versions') }}</dt>
${config.versions.active
.map(
(version) => `
<dd ${version.slug === config.versions.current.slug ? 'class="rtd-current-item"' : ""}>
<a href="${version.urls.documentation}">${version.slug}</a>
</dd>
`,
)
.join("\n")}
</dl>
`;
return versionsHTML;
}
function renderDownloads(config) {
if (!Object.keys(config.versions.current.downloads).length) {
return "";
}
const downloadsNameDisplay = {
pdf: "PDF",
epub: "Epub",
htmlzip: "HTML",
};
const downloadsHTML = `
<dl>
<dt>{{ _('Downloads') }}</dt>
${Object.entries(config.versions.current.downloads)
.map(
([name, url]) => `
<dd>
<a href="${url}">${downloadsNameDisplay[name]}</a>
</dd>
`,
)
.join("\n")}
</dl>
`;
return downloadsHTML;
}
document.addEventListener("readthedocs-addons-data-ready", function (event) {
const config = event.detail.data();
const flyout = `
<div class="rst-versions" data-toggle="rst-versions" role="note">
<span class="rst-current-version" data-toggle="rst-current-version">
<span class="fa fa-book"> Read the Docs</span>
v: ${config.versions.current.slug}
<span class="fa fa-caret-down"></span>
</span>
<div class="rst-other-versions">
<div class="injected">
${renderLanguages(config)}
${renderVersions(config)}
${renderDownloads(config)}
<dl>
<dt>{{ _('On Read the Docs') }}</dt>
<dd>
<a href="${config.projects.current.urls.home}">{{ _('Project Home') }}</a>
</dd>
<dd>
<a href="${config.projects.current.urls.builds}">{{ _('Builds') }}</a>
</dd>
<dd>
<a href="${config.projects.current.urls.downloads}">{{ _('Downloads') }}</a>
</dd>
</dl>
<dl>
<dt>{{ _('Search') }}</dt>
<dd>
<form id="flyout-search-form">
<input
class="wy-form"
type="text"
name="q"
aria-label="{{ _('Search docs') }}"
placeholder="{{ _('Search docs') }}"
/>
</form>
</dd>
</dl>
<hr />
<small>
<span>Hosted by <a href="https://about.readthedocs.org/?utm_source={{ READTHEDOCS_PROJECT }}&utm_content=flyout">Read the Docs</a></span>
</small>
</div>
</div>
`;
// Inject the generated flyout into the body HTML element.
document.body.insertAdjacentHTML("beforeend", flyout);
// Trigger the Read the Docs Addons Search modal when clicking on the "Search docs" input from inside the flyout.
document
.querySelector("#flyout-search-form")
.addEventListener("focusin", () => {
const event = new CustomEvent("readthedocs-search-show");
document.dispatchEvent(event);
});
})
}
if (themeLanguageSelector || themeVersionSelector) {
function onSelectorSwitch(event) {
const option = event.target.selectedIndex;