Skip to content

Only load searchindex when needed #2553

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion src/front-end/css/chrome.css
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,34 @@ mark.fade-out {
max-width: var(--content-max-width);
}

#searchbar-outer.searching #searchbar {
padding-right: 30px;
}
#searchbar-outer .spinner-wrapper {
display: none;
}
#searchbar-outer.searching .spinner-wrapper {
display: block;
}

.search-wrapper {
position: relative;
}

.spinner-wrapper {
--spinner-margin: 2px;
position: absolute;
margin-block-start: calc(var(--searchbar-margin-block-start) + var(--spinner-margin));
right: var(--spinner-margin);
top: 0;
bottom: var(--spinner-margin);
padding: 6px;
background-color: var(--bg);
}

#searchbar {
width: 100%;
margin-block-start: 5px;
margin-block-start: var(--searchbar-margin-block-start);
margin-block-end: 0;
margin-inline-start: auto;
margin-inline-end: auto;
Expand Down
1 change: 1 addition & 0 deletions src/front-end/css/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
--menu-bar-height: 50px;
--mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace;
--code-font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */
--searchbar-margin-block-start: 5px;
}

/* Themes */
Expand Down
52 changes: 36 additions & 16 deletions src/front-end/searcher/searcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ window.search = window.search || {};
}

const search_wrap = document.getElementById('search-wrapper'),
searchbar_outer = document.getElementById('searchbar-outer'),
searchbar = document.getElementById('searchbar'),
searchresults = document.getElementById('searchresults'),
searchresults_outer = document.getElementById('searchresults-outer'),
Expand Down Expand Up @@ -267,6 +268,18 @@ window.search = window.search || {};
doc_urls = config.doc_urls;
searchindex = elasticlunr.Index.load(config.index);

searchbar_outer.classList.remove('searching');

searchbar.focus();

const searchterm = searchbar.value.trim();
if (searchterm !== '') {
searchbar.classList.add('active');
doSearch(searchterm);
}
}

function initSearchInteractions() {
// Set up events
searchicon.addEventListener('click', () => {
searchIconClickHandler();
Expand All @@ -290,6 +303,8 @@ window.search = window.search || {};
doSearchOrMarkFromUrl();
}

initSearchInteractions();

function unfocusSearchbar() {
// hacky, but just focusing a div only works once
const tmp = document.createElement('input');
Expand Down Expand Up @@ -396,8 +411,25 @@ window.search = window.search || {};
}
}

function loadSearchScript(url, id) {
if (document.getElementById(id)) {
return;
}
searchbar_outer.classList.add('searching');

const script = document.createElement('script');
script.src = url;
script.id = id;
script.onload = () => init(window.search);
script.onerror = error => {
console.error(`Failed to load \`${url}\`: ${error}`);
};
document.head.append(script);
}

function showSearch(yes) {
if (yes) {
loadSearchScript(path_to_root + '{{ resource "searchindex.js" }}', 'search-index');
search_wrap.classList.remove('hidden');
searchicon.setAttribute('aria-expanded', 'true');
} else {
Expand Down Expand Up @@ -480,14 +512,14 @@ window.search = window.search || {};
// Don't search the same twice
if (current_searchterm === searchterm) {
return;
} else {
current_searchterm = searchterm;
}

searchbar_outer.classList.add('searching');
if (searchindex === null) {
return;
}

current_searchterm = searchterm;

// Do the actual search
const results = searchindex.search(searchterm, search_options);
const resultcount = Math.min(results.length, results_options.limit_results);
Expand All @@ -506,21 +538,9 @@ window.search = window.search || {};

// Display results
showResults(true);
searchbar_outer.classList.remove('searching');
}

function loadScript(url, id) {
const script = document.createElement('script');
script.src = url;
script.id = id;
script.onload = () => init(window.search);
script.onerror = error => {
console.error(`Failed to load \`${url}\`: ${error}`);
};
document.head.append(script);
}

loadScript(path_to_root + '{{ resource "searchindex.js" }}', 'search-index');

// Exported functions
search.hasFocus = hasFocus;
})(window.search);
7 changes: 6 additions & 1 deletion src/front-end/templates/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,12 @@
{{#if search_enabled}}
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
<div class="search-wrapper">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
<div class="spinner-wrapper">
<i class="fa fa-spinner fa-spin"></i>
</div>
</div>
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
Expand Down
42 changes: 42 additions & 0 deletions tests/gui/search.goml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,45 @@ assert-text: ("#searchresults-header", "")
call-function: ("open-search", {})
write: "strikethrough"
wait-for-text: ("#searchresults-header", "2 search results for 'strikethrough':")

// Now we test search shortcuts and more page changes.
go-to: |DOC_PATH| + "index.html"

// This check is to ensure that the search bar is inside the search wrapper.
assert: "#search-wrapper #searchbar"
assert-css: ("#search-wrapper", {"display": "none"})

// Now we make the search input appear with the `S` shortcut.
press-key: 'S'
wait-for-css: ("#search-wrapper", {"display": "block"})
// We ensure the search bar has the focus.
assert: "#searchbar:focus"

// Now we press `Escape` to ensure that the search input disappears again.
press-key: 'Escape'
wait-for-css: ("#search-wrapper", {"display": "none"})

// Making it appear by clicking on the search button.
click: "#search-toggle"
wait-for-css: ("#search-wrapper", {"display": "block"})
// We ensure the search bar has the focus.
assert: "#searchbar:focus"

// We input "test".
write: "test"
// The results should now appear.
wait-for-text: ("#searchresults-header", "search results for 'test':", ENDS_WITH)
assert: "#searchresults"
// Ensure that the URL was updated as well.
assert-document-property: ({"URL": "?search=test"}, ENDS_WITH)

// Now we ensure that when we land on the page with a "search in progress", the search results are
// loaded and that the search input has focus.
go-to: |DOC_PATH| + "index.html?search=test"
wait-for-text: ("#searchresults-header", "search results for 'test':", ENDS_WITH)
assert: "#searchbar:focus"
assert: "#searchresults"

// And now we press `Escape` to close everything.
press-key: 'Escape'
wait-for-css: ("#search-wrapper", {"display": "none"})