Skip to content

Commit 3b1f7bc

Browse files
committed
rustdoc-search: fix back/forward interaction after reload
1 parent 90c14a5 commit 3b1f7bc

File tree

2 files changed

+58
-52
lines changed

2 files changed

+58
-52
lines changed

src/librustdoc/html/static/js/main.js

+58
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,64 @@ function preLoadCss(cssUrl) {
377377
};
378378
}
379379

380+
// Push and pop states are used to add search results to the browser
381+
// history.
382+
if (browserSupportsHistoryApi()) {
383+
// Store the previous <title> so we can revert back to it later.
384+
const previousTitle = document.title;
385+
386+
window.addEventListener("popstate", e => {
387+
const params = searchState.getQueryStringParams();
388+
// Revert to the previous title manually since the History
389+
// API ignores the title parameter.
390+
document.title = previousTitle;
391+
// Synchronize search bar with query string state and
392+
// perform the search. This will empty the bar if there's
393+
// nothing there, which lets you really go back to a
394+
// previous state with nothing in the bar.
395+
if (params.search !== undefined) {
396+
loadSearch();
397+
searchState.inputElement().value = params.search;
398+
// Some browsers fire "onpopstate" for every page load
399+
// (Chrome), while others fire the event only when actually
400+
// popping a state (Firefox), which is why search() is
401+
// called both here and at the end of the startSearch()
402+
// function.
403+
e.preventDefault();
404+
searchState.showResults();
405+
if (params.search === "") {
406+
searchState.focus();
407+
}
408+
} else {
409+
// When browsing back from search results the main page
410+
// visibility must be reset.
411+
searchState.hideResults();
412+
}
413+
});
414+
}
415+
416+
// This is required in firefox to avoid this problem: Navigating to a search result
417+
// with the keyboard, hitting enter, and then hitting back would take you back to
418+
// the doc page, rather than the search that should overlay it.
419+
// This was an interaction between the back-forward cache and our handlers
420+
// that try to sync state between the URL and the search input. To work around it,
421+
// do a small amount of re-init on page show.
422+
window.onpageshow = () => {
423+
const qSearch = searchState.getQueryStringParams().search;
424+
if (qSearch !== undefined) {
425+
if (searchState.inputElement().value === "") {
426+
searchState.inputElement().value = qSearch;
427+
}
428+
searchState.showResults();
429+
if (qSearch === "") {
430+
loadSearch();
431+
searchState.focus();
432+
}
433+
} else {
434+
searchState.hideResults();
435+
}
436+
};
437+
380438
const params = searchState.getQueryStringParams();
381439
if (params.search !== undefined) {
382440
searchState.setLoadingSearch();

src/librustdoc/html/static/js/search.js

-52
Original file line numberDiff line numberDiff line change
@@ -4814,58 +4814,6 @@ function registerSearchEvents() {
48144814
searchState.inputElement().addEventListener("blur", () => {
48154815
searchState.inputElement().placeholder = searchState.inputElement().origPlaceholder;
48164816
});
4817-
4818-
// Push and pop states are used to add search results to the browser
4819-
// history.
4820-
if (browserSupportsHistoryApi()) {
4821-
// Store the previous <title> so we can revert back to it later.
4822-
const previousTitle = document.title;
4823-
4824-
window.addEventListener("popstate", e => {
4825-
const params = searchState.getQueryStringParams();
4826-
// Revert to the previous title manually since the History
4827-
// API ignores the title parameter.
4828-
document.title = previousTitle;
4829-
// When browsing forward to search results the previous
4830-
// search will be repeated, so the currentResults are
4831-
// cleared to ensure the search is successful.
4832-
currentResults = null;
4833-
// Synchronize search bar with query string state and
4834-
// perform the search. This will empty the bar if there's
4835-
// nothing there, which lets you really go back to a
4836-
// previous state with nothing in the bar.
4837-
if (params.search !== undefined) {
4838-
searchState.inputElement().value = params.search;
4839-
// Some browsers fire "onpopstate" for every page load
4840-
// (Chrome), while others fire the event only when actually
4841-
// popping a state (Firefox), which is why search() is
4842-
// called both here and at the end of the startSearch()
4843-
// function.
4844-
e.preventDefault();
4845-
search();
4846-
} else {
4847-
// When browsing back from search results the main page
4848-
// visibility must be reset.
4849-
searchState.hideResults();
4850-
}
4851-
});
4852-
}
4853-
4854-
// This is required in firefox to avoid this problem: Navigating to a search result
4855-
// with the keyboard, hitting enter, and then hitting back would take you back to
4856-
// the doc page, rather than the search that should overlay it.
4857-
// This was an interaction between the back-forward cache and our handlers
4858-
// that try to sync state between the URL and the search input. To work around it,
4859-
// do a small amount of re-init on page show.
4860-
window.onpageshow = () => {
4861-
const qSearch = searchState.getQueryStringParams().search;
4862-
if (qSearch !== undefined) {
4863-
if (searchState.inputElement().value === "") {
4864-
searchState.inputElement().value = qSearch;
4865-
}
4866-
search();
4867-
}
4868-
};
48694817
}
48704818

48714819
function updateCrate(ev) {

0 commit comments

Comments
 (0)