about summary refs log tree commit diff
path: root/src/librustdoc/html
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustdoc/html')
-rw-r--r--src/librustdoc/html/render.rs39
-rw-r--r--src/librustdoc/html/render/cache.rs7
2 files changed, 41 insertions, 5 deletions
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index da020b85ed4..b91aab44f10 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -789,6 +789,37 @@ themePicker.onblur = handleThemeButtonsBlur;
         Ok((ret, krates))
     }
 
+    fn collect_json(path: &Path, krate: &str) -> io::Result<(Vec<String>, Vec<String>)> {
+        let mut ret = Vec::new();
+        let mut krates = Vec::new();
+
+        if path.exists() {
+            for line in BufReader::new(File::open(path)?).lines() {
+                let line = line?;
+                if !line.starts_with("\"") {
+                    continue;
+                }
+                if line.starts_with(&format!("\"{}\"", krate)) {
+                    continue;
+                }
+                if line.ends_with(",\\") {
+                    ret.push(line[..line.len() - 2].to_string());
+                } else {
+                    // Ends with "\\" (it's the case for the last added crate line)
+                    ret.push(line[..line.len() - 1].to_string());
+                }
+                krates.push(
+                    line.split('"')
+                        .filter(|s| !s.is_empty())
+                        .next()
+                        .map(|s| s.to_owned())
+                        .unwrap_or_else(String::new),
+                );
+            }
+        }
+        Ok((ret, krates))
+    }
+
     fn show_item(item: &IndexItem, krate: &str) -> String {
         format!(
             "{{'crate':'{}','ty':{},'name':'{}','desc':'{}','p':'{}'{}}}",
@@ -909,18 +940,18 @@ themePicker.onblur = handleThemeButtonsBlur;
 
     // Update the search index
     let dst = cx.dst.join(&format!("search-index{}.js", cx.shared.resource_suffix));
-    let (mut all_indexes, mut krates) = try_err!(collect(&dst, &krate.name, "searchIndex"), &dst);
+    let (mut all_indexes, mut krates) = try_err!(collect_json(&dst, &krate.name), &dst);
     all_indexes.push(search_index);
 
     // Sort the indexes by crate so the file will be generated identically even
     // with rustdoc running in parallel.
     all_indexes.sort();
     {
-        let mut v = String::from("var searchIndex={};\n");
-        v.push_str(&all_indexes.join("\n"));
+        let mut v = String::from("var searchIndex = JSON.parse('{\\\n");
+        v.push_str(&all_indexes.join(",\\\n"));
         // "addSearchOptions" has to be called first so the crate filtering can be set before the
         // search might start (if it's set into the URL for example).
-        v.push_str("\naddSearchOptions(searchIndex);initSearch(searchIndex);");
+        v.push_str("\\\n}');\naddSearchOptions(searchIndex);initSearch(searchIndex);");
         cx.shared.fs.write(&dst, &v)?;
     }
     if options.enable_index_page {
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index f3c5c12810b..5b090291227 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -634,7 +634,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
 
     // Collect the index into a string
     format!(
-        r#"searchIndex["{}"] = {};"#,
+        r#""{}":{}"#,
         krate.name,
         serde_json::to_string(&CrateData {
             doc: crate_doc,
@@ -642,6 +642,11 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
             paths: crate_paths,
         })
         .expect("failed serde conversion")
+        // All these `replace` calls are because we have to go through JS string for JSON content.
+        .replace(r"\", r"\\")
+        .replace("'", r"\'")
+        // We need to escape double quotes for the JSON.
+        .replace("\\\"", "\\\\\"")
     )
 }