2 /* global sourcesIndex */
4 // Local js definitions:
5 /* global addClass, getCurrentValue, hasClass, onEachLazy, removeClass, browserSupportsHistoryApi */
6 /* global updateLocalStorage */
12 const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value;
14 function createDirEntry(elem, parent, fullPath, hasFoundFile) {
15 const name = document.createElement("div");
16 name.className = "name";
18 fullPath += elem["name"] + "/";
20 name.onclick = ev => {
21 if (hasClass(ev.target, "expand")) {
22 removeClass(ev.target, "expand");
24 addClass(ev.target, "expand");
27 name.innerText = elem["name"];
29 const children = document.createElement("div");
30 children.className = "children";
31 const folders = document.createElement("div");
32 folders.className = "folders";
34 for (const dir of elem.dirs) {
35 if (createDirEntry(dir, folders, fullPath, hasFoundFile)) {
36 addClass(name, "expand");
41 children.appendChild(folders);
43 const files = document.createElement("div");
44 files.className = "files";
46 for (const file_text of elem.files) {
47 const file = document.createElement("a");
48 file.innerText = file_text;
49 file.href = rootPath + "src/" + fullPath + file_text + ".html";
50 const w = window.location.href.split("#")[0];
51 if (!hasFoundFile && w === file.href) {
52 file.className = "selected";
53 addClass(name, "expand");
56 files.appendChild(file);
59 children.appendChild(files);
60 parent.appendChild(name);
61 parent.appendChild(children);
65 function toggleSidebar() {
66 const child = this.children[0];
67 if (child.innerText === ">") {
68 addClass(document.documentElement, "source-sidebar-expanded");
69 child.innerText = "<";
70 updateLocalStorage("source-sidebar-show", "true");
72 removeClass(document.documentElement, "source-sidebar-expanded");
73 child.innerText = ">";
74 updateLocalStorage("source-sidebar-show", "false");
78 function createSidebarToggle() {
79 const sidebarToggle = document.createElement("div");
80 sidebarToggle.id = "sidebar-toggle";
81 sidebarToggle.onclick = toggleSidebar;
83 const inner = document.createElement("div");
85 if (getCurrentValue("source-sidebar-show") === "true") {
86 inner.innerText = "<";
88 inner.innerText = ">";
91 sidebarToggle.appendChild(inner);
95 // This function is called from "source-files.js", generated in `html/render/mod.rs`.
96 // eslint-disable-next-line no-unused-vars
97 function createSourceSidebar() {
98 const container = document.querySelector("nav.sidebar");
100 const sidebarToggle = createSidebarToggle();
101 container.insertBefore(sidebarToggle, container.firstChild);
103 const sidebar = document.createElement("div");
104 sidebar.id = "source-sidebar";
106 let hasFoundFile = false;
108 const title = document.createElement("div");
109 title.className = "title";
110 title.innerText = "Files";
111 sidebar.appendChild(title);
112 Object.keys(sourcesIndex).forEach(key => {
113 sourcesIndex[key].name = key;
114 hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "",
118 container.appendChild(sidebar);
119 // Focus on the current file in the source files sidebar.
120 const selected_elem = sidebar.getElementsByClassName("selected")[0];
121 if (typeof selected_elem !== "undefined") {
122 selected_elem.focus();
126 const lineNumbersRegex = /^#?(\d+)(?:-(\d+))?$/;
128 function highlightSourceLines(match) {
129 if (typeof match === "undefined") {
130 match = window.location.hash.match(lineNumbersRegex);
135 let from = parseInt(match[1], 10);
137 if (typeof match[2] !== "undefined") {
138 to = parseInt(match[2], 10);
145 let elem = document.getElementById(from);
149 const x = document.getElementById(from);
153 onEachLazy(document.getElementsByClassName("line-numbers"), e => {
154 onEachLazy(e.getElementsByTagName("span"), i_e => {
155 removeClass(i_e, "line-highlighted");
158 for (let i = from; i <= to; ++i) {
159 elem = document.getElementById(i);
163 addClass(elem, "line-highlighted");
167 const handleSourceHighlight = (function() {
168 let prev_line_id = 0;
170 const set_fragment = name => {
171 const x = window.scrollX,
173 if (browserSupportsHistoryApi()) {
174 history.replaceState(null, null, "#" + name);
175 highlightSourceLines();
177 location.replace("#" + name);
179 // Prevent jumps when selecting one or many lines
180 window.scrollTo(x, y);
184 let cur_line_id = parseInt(ev.target.id, 10);
185 // It can happen when clicking not on a line number span.
186 if (isNaN(cur_line_id)) {
191 if (ev.shiftKey && prev_line_id) {
192 // Swap selection if needed
193 if (prev_line_id > cur_line_id) {
194 const tmp = prev_line_id;
195 prev_line_id = cur_line_id;
199 set_fragment(prev_line_id + "-" + cur_line_id);
201 prev_line_id = cur_line_id;
203 set_fragment(cur_line_id);
208 window.addEventListener("hashchange", () => {
209 const match = window.location.hash.match(lineNumbersRegex);
211 return highlightSourceLines(match);
215 onEachLazy(document.getElementsByClassName("line-numbers"), el => {
216 el.addEventListener("click", handleSourceHighlight);
219 highlightSourceLines();
221 window.createSourceSidebar = createSourceSidebar;