mirror of
https://github.com/rust-lang/mdBook
synced 2024-12-14 06:42:35 +00:00
Use JSON search index with JS fallback
This allows the search index to be loaded asynchronously, and should use fewer resources as it doesn't have to execute the JS. JS loading is kept as a fallback for CORS issues with file:// URIs in Chrome.
This commit is contained in:
parent
62c8311301
commit
e1a46d213e
2 changed files with 22 additions and 15 deletions
|
@ -24,14 +24,15 @@ pub fn create_files(search_config: &Search, destination: &Path, book: &Book) ->
|
|||
render_item(&mut index, &search_config, &mut doc_urls, item)?;
|
||||
}
|
||||
|
||||
let index = write_to_js(index, &search_config, doc_urls)?;
|
||||
let index = write_to_json(index, &search_config, doc_urls)?;
|
||||
debug!("Writing search index ✓");
|
||||
if index.len() > 10_000_000 {
|
||||
warn!("searchindex.js is very large ({} bytes)", index.len());
|
||||
warn!("searchindex.json is very large ({} bytes)", index.len());
|
||||
}
|
||||
|
||||
if search_config.copy_js {
|
||||
utils::fs::write_file(destination, "searchindex.js", index.as_bytes())?;
|
||||
utils::fs::write_file(destination, "searchindex.json", index.as_bytes())?;
|
||||
utils::fs::write_file(destination, "searchindex.js", format!("window.search = {};", index).as_bytes())?;
|
||||
utils::fs::write_file(destination, "searcher.js", searcher::JS)?;
|
||||
utils::fs::write_file(destination, "mark.min.js", searcher::MARK_JS)?;
|
||||
utils::fs::write_file(destination, "elasticlunr.min.js", searcher::ELASTICLUNR_JS)?;
|
||||
|
@ -164,10 +165,7 @@ fn render_item(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Exports the index and search options to a JS script which stores the index in `window.search`.
|
||||
/// Using a JS script is a workaround for CORS in `file://` URIs. It also removes the need for
|
||||
/// downloading/parsing JSON in JS.
|
||||
fn write_to_js(index: Index, search_config: &Search, doc_urls: Vec<String>) -> Result<String> {
|
||||
fn write_to_json(index: Index, search_config: &Search, doc_urls: Vec<String>) -> Result<String> {
|
||||
use std::collections::BTreeMap;
|
||||
use self::elasticlunr::config::{SearchBool, SearchOptions, SearchOptionsField};
|
||||
|
||||
|
@ -225,7 +223,7 @@ fn write_to_js(index: Index, search_config: &Search, doc_urls: Vec<String>) -> R
|
|||
let json_contents = serde_json::to_value(&json_contents)?;
|
||||
let json_contents = serde_json::to_string(&json_contents)?;
|
||||
|
||||
Ok(format!("window.search = {};", json_contents))
|
||||
Ok(json_contents)
|
||||
}
|
||||
|
||||
fn clean_html(html: &str) -> String {
|
||||
|
|
|
@ -247,12 +247,12 @@ window.search = window.search || {};
|
|||
return teaser_split.join('');
|
||||
}
|
||||
|
||||
function init() {
|
||||
results_options = window.search.results_options;
|
||||
search_options = window.search.search_options;
|
||||
searchbar_outer = window.search.searchbar_outer;
|
||||
doc_urls = window.search.doc_urls;
|
||||
searchindex = elasticlunr.Index.load(window.search.index);
|
||||
function init(config) {
|
||||
results_options = config.results_options;
|
||||
search_options = config.search_options;
|
||||
searchbar_outer = config.searchbar_outer;
|
||||
doc_urls = config.doc_urls;
|
||||
searchindex = elasticlunr.Index.load(config.index);
|
||||
|
||||
// Set up events
|
||||
searchicon.addEventListener('click', function(e) { searchIconClickHandler(); }, false);
|
||||
|
@ -462,7 +462,16 @@ window.search = window.search || {};
|
|||
showResults(true);
|
||||
}
|
||||
|
||||
init();
|
||||
fetch('searchindex.json')
|
||||
.then(response => response.json())
|
||||
.then(json => init(json))
|
||||
.catch(error => { // Try to load searchindex.js if fetch failed
|
||||
var script = document.createElement('script');
|
||||
script.src = 'searchindex.js';
|
||||
script.onload = () => init(window.search);
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
|
||||
// Exported functions
|
||||
search.hasFocus = hasFocus;
|
||||
})(window.search);
|
||||
|
|
Loading…
Reference in a new issue