1const themeFlyoutDisplay = "hidden"; 2const themeVersionSelector = true; 3const themeLanguageSelector = true; 4 5if (themeFlyoutDisplay === "attached") { 6 function renderLanguages(config) { 7 if (!config.projects.translations.length) { 8 return ""; 9 } 10 11 // Insert the current language to the options on the selector 12 let languages = config.projects.translations.concat(config.projects.current); 13 languages = languages.sort((a, b) => a.language.name.localeCompare(b.language.name)); 14 15 const languagesHTML = ` 16 <dl> 17 <dt>Languages</dt> 18 ${languages 19 .map( 20 (translation) => ` 21 <dd ${translation.slug == config.projects.current.slug ? 'class="rtd-current-item"' : ""}> 22 <a href="${translation.urls.documentation}">${translation.language.code}</a> 23 </dd> 24 `, 25 ) 26 .join("\n")} 27 </dl> 28 `; 29 return languagesHTML; 30 } 31 32 function renderVersions(config) { 33 if (!config.versions.active.length) { 34 return ""; 35 } 36 const versionsHTML = ` 37 <dl> 38 <dt>Versions</dt> 39 ${config.versions.active 40 .map( 41 (version) => ` 42 <dd ${version.slug === config.versions.current.slug ? 'class="rtd-current-item"' : ""}> 43 <a href="${version.urls.documentation}">${version.slug}</a> 44 </dd> 45 `, 46 ) 47 .join("\n")} 48 </dl> 49 `; 50 return versionsHTML; 51 } 52 53 function renderDownloads(config) { 54 if (!Object.keys(config.versions.current.downloads).length) { 55 return ""; 56 } 57 const downloadsNameDisplay = { 58 pdf: "PDF", 59 epub: "Epub", 60 htmlzip: "HTML", 61 }; 62 63 const downloadsHTML = ` 64 <dl> 65 <dt>Downloads</dt> 66 ${Object.entries(config.versions.current.downloads) 67 .map( 68 ([name, url]) => ` 69 <dd> 70 <a href="${url}">${downloadsNameDisplay[name]}</a> 71 </dd> 72 `, 73 ) 74 .join("\n")} 75 </dl> 76 `; 77 return downloadsHTML; 78 } 79 80 document.addEventListener("readthedocs-addons-data-ready", function (event) { 81 const config = event.detail.data(); 82 83 const flyout = ` 84 <div class="rst-versions" data-toggle="rst-versions" role="note"> 85 <span class="rst-current-version" data-toggle="rst-current-version"> 86 <span class="fa fa-book"> Read the Docs</span> 87 v: ${config.versions.current.slug} 88 <span class="fa fa-caret-down"></span> 89 </span> 90 <div class="rst-other-versions"> 91 <div class="injected"> 92 ${renderLanguages(config)} 93 ${renderVersions(config)} 94 ${renderDownloads(config)} 95 <dl> 96 <dt>On Read the Docs</dt> 97 <dd> 98 <a href="${config.projects.current.urls.home}">Project Home</a> 99 </dd> 100 <dd> 101 <a href="${config.projects.current.urls.builds}">Builds</a> 102 </dd> 103 <dd> 104 <a href="${config.projects.current.urls.downloads}">Downloads</a> 105 </dd> 106 </dl> 107 <dl> 108 <dt>Search</dt> 109 <dd> 110 <form id="flyout-search-form"> 111 <input 112 class="wy-form" 113 type="text" 114 name="q" 115 aria-label="Search docs" 116 placeholder="Search docs" 117 /> 118 </form> 119 </dd> 120 </dl> 121 <hr /> 122 <small> 123 <span>Hosted by <a href="https://about.readthedocs.org/?utm_source=&utm_content=flyout">Read the Docs</a></span> 124 </small> 125 </div> 126 </div> 127 `; 128 129 // Inject the generated flyout into the body HTML element. 130 document.body.insertAdjacentHTML("beforeend", flyout); 131 132 // Trigger the Read the Docs Addons Search modal when clicking on the "Search docs" input from inside the flyout. 133 document 134 .querySelector("#flyout-search-form") 135 .addEventListener("focusin", () => { 136 const event = new CustomEvent("readthedocs-search-show"); 137 document.dispatchEvent(event); 138 }); 139 }) 140} 141 142if (themeLanguageSelector || themeVersionSelector) { 143 function onSelectorSwitch(event) { 144 const option = event.target.selectedIndex; 145 const item = event.target.options[option]; 146 window.location.href = item.dataset.url; 147 } 148 149 document.addEventListener("readthedocs-addons-data-ready", function (event) { 150 const config = event.detail.data(); 151 152 const versionSwitch = document.querySelector( 153 "div.switch-menus > div.version-switch", 154 ); 155 if (themeVersionSelector) { 156 let versions = config.versions.active; 157 if (config.versions.current.hidden || config.versions.current.type === "external") { 158 versions.unshift(config.versions.current); 159 } 160 const versionSelect = ` 161 <select> 162 ${versions 163 .map( 164 (version) => ` 165 <option 166 value="${version.slug}" 167 ${config.versions.current.slug === version.slug ? 'selected="selected"' : ""} 168 data-url="${version.urls.documentation}"> 169 ${version.slug} 170 </option>`, 171 ) 172 .join("\n")} 173 </select> 174 `; 175 176 versionSwitch.innerHTML = versionSelect; 177 versionSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); 178 } 179 180 const languageSwitch = document.querySelector( 181 "div.switch-menus > div.language-switch", 182 ); 183 184 if (themeLanguageSelector) { 185 if (config.projects.translations.length) { 186 // Add the current language to the options on the selector 187 let languages = config.projects.translations.concat( 188 config.projects.current, 189 ); 190 languages = languages.sort((a, b) => 191 a.language.name.localeCompare(b.language.name), 192 ); 193 194 const languageSelect = ` 195 <select> 196 ${languages 197 .map( 198 (language) => ` 199 <option 200 value="${language.language.code}" 201 ${config.projects.current.slug === language.slug ? 'selected="selected"' : ""} 202 data-url="${language.urls.documentation}"> 203 ${language.language.name} 204 </option>`, 205 ) 206 .join("\n")} 207 </select> 208 `; 209 210 languageSwitch.innerHTML = languageSelect; 211 languageSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); 212 } 213 else { 214 languageSwitch.remove(); 215 } 216 } 217 }); 218} 219 220document.addEventListener("readthedocs-addons-data-ready", function (event) {
221 // Trigger the Read the Docs Addons Search modal when clicking on "Search docs" input from the topnav. 222 document 223 .querySelector("[role='search'] input") 224 .addEventListener("focusin", () => { 225 const event = new CustomEvent("readthedocs-search-show"); 226 document.dispatchEvent(event); 227 }); 228});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.