diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 27ad91d09e064..6fb41ff327916 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -366,13 +366,15 @@ pub(super) fn write_shared(
.collect::>();
files.sort_unstable();
let subs = subs.iter().map(|s| s.to_json_string()).collect::>().join(",");
- let dirs =
- if subs.is_empty() { String::new() } else { format!(",\"dirs\":[{}]", subs) };
+ let dirs = if subs.is_empty() && files.is_empty() {
+ String::new()
+ } else {
+ format!(",[{}]", subs)
+ };
let files = files.join(",");
- let files =
- if files.is_empty() { String::new() } else { format!(",\"files\":[{}]", files) };
+ let files = if files.is_empty() { String::new() } else { format!(",[{}]", files) };
format!(
- "{{\"name\":\"{name}\"{dirs}{files}}}",
+ "[\"{name}\"{dirs}{files}]",
name = self.elem.to_str().expect("invalid osstring conversion"),
dirs = dirs,
files = files
@@ -411,18 +413,23 @@ pub(super) fn write_shared(
let dst = cx.dst.join(&format!("source-files{}.js", cx.shared.resource_suffix));
let make_sources = || {
let (mut all_sources, _krates) =
- try_err!(collect(&dst, krate.name(cx.tcx()).as_str(), "sourcesIndex"), &dst);
+ try_err!(collect_json(&dst, krate.name(cx.tcx()).as_str()), &dst);
all_sources.push(format!(
- "sourcesIndex[\"{}\"] = {};",
+ r#""{}":{}"#,
&krate.name(cx.tcx()),
- hierarchy.to_json_string()
+ hierarchy
+ .to_json_string()
+ // All these `replace` calls are because we have to go through JS string for JSON content.
+ .replace('\\', r"\\")
+ .replace('\'', r"\'")
+ // We need to escape double quotes for the JSON.
+ .replace("\\\"", "\\\\\"")
));
all_sources.sort();
- Ok(format!(
- "var sourcesIndex = {{}};\n{}\ncreateSourceSidebar();\n",
- all_sources.join("\n")
- )
- .into_bytes())
+ let mut v = String::from("var sourcesIndex = JSON.parse('{\\\n");
+ v.push_str(&all_sources.join(",\\\n"));
+ v.push_str("\\\n}');\ncreateSourceSidebar();\n");
+ Ok(v.into_bytes())
};
write_crate("source-files.js", &make_sources)?;
}
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index a6a0b09ef31fe..c45d614293a85 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -12,6 +12,10 @@
const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value;
let oldScrollPosition = 0;
+const NAME_OFFSET = 0;
+const DIRS_OFFSET = 1;
+const FILES_OFFSET = 2;
+
function closeSidebarIfMobile() {
if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) {
updateLocalStorage("source-sidebar-show", "false");
@@ -24,15 +28,15 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) {
dirEntry.className = "dir-entry";
- fullPath += elem["name"] + "/";
+ fullPath += elem[NAME_OFFSET] + "/";
- summary.innerText = elem["name"];
+ summary.innerText = elem[NAME_OFFSET];
dirEntry.appendChild(summary);
const folders = document.createElement("div");
folders.className = "folders";
- if (elem.dirs) {
- for (const dir of elem.dirs) {
+ if (elem[DIRS_OFFSET]) {
+ for (const dir of elem[DIRS_OFFSET]) {
if (createDirEntry(dir, folders, fullPath, false)) {
dirEntry.open = true;
hasFoundFile = true;
@@ -43,8 +47,8 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) {
const files = document.createElement("div");
files.className = "files";
- if (elem.files) {
- for (const file_text of elem.files) {
+ if (elem[FILES_OFFSET]) {
+ for (const file_text of elem[FILES_OFFSET]) {
const file = document.createElement("a");
file.innerText = file_text;
file.href = rootPath + "src/" + fullPath + file_text + ".html";
@@ -125,7 +129,7 @@ function createSourceSidebar() {
title.innerText = "Files";
sidebar.appendChild(title);
Object.keys(sourcesIndex).forEach(key => {
- sourcesIndex[key].name = key;
+ sourcesIndex[key][NAME_OFFSET] = key;
hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "",
hasFoundFile);
});