Skip to content

Commit

Permalink
rustdoc-search: fix back/forward interaction after reload
Browse files Browse the repository at this point in the history
  • Loading branch information
notriddle committed Jan 13, 2025
1 parent 7b06127 commit 27f875a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 52 deletions.
58 changes: 58 additions & 0 deletions src/librustdoc/html/static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,64 @@ function preLoadCss(cssUrl) {
};
}

// Push and pop states are used to add search results to the browser
// history.
if (browserSupportsHistoryApi()) {
// Store the previous <title> so we can revert back to it later.
const previousTitle = document.title;

window.addEventListener("popstate", e => {
const params = searchState.getQueryStringParams();
// Revert to the previous title manually since the History
// API ignores the title parameter.
document.title = previousTitle;
// Synchronize search bar with query string state and
// perform the search. This will empty the bar if there's
// nothing there, which lets you really go back to a
// previous state with nothing in the bar.
if (params.search !== undefined) {
loadSearch();
searchState.inputElement().value = params.search;
// Some browsers fire "onpopstate" for every page load
// (Chrome), while others fire the event only when actually
// popping a state (Firefox), which is why search() is
// called both here and at the end of the startSearch()
// function.
e.preventDefault();
searchState.showResults();
if (params.search === "") {
searchState.focus();
}
} else {
// When browsing back from search results the main page
// visibility must be reset.
searchState.hideResults();
}
});
}

// This is required in firefox to avoid this problem: Navigating to a search result
// with the keyboard, hitting enter, and then hitting back would take you back to
// the doc page, rather than the search that should overlay it.
// This was an interaction between the back-forward cache and our handlers
// that try to sync state between the URL and the search input. To work around it,
// do a small amount of re-init on page show.
window.onpageshow = () => {
const qSearch = searchState.getQueryStringParams().search;
if (qSearch !== undefined) {
if (searchState.inputElement().value === "") {
searchState.inputElement().value = qSearch;
}
searchState.showResults();
if (qSearch === "") {
loadSearch();
searchState.focus();
}
} else {
searchState.hideResults();
}
};

const params = searchState.getQueryStringParams();
if (params.search !== undefined) {
searchState.setLoadingSearch();
Expand Down
52 changes: 0 additions & 52 deletions src/librustdoc/html/static/js/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -4819,58 +4819,6 @@ function registerSearchEvents() {
searchState.inputElement().addEventListener("blur", () => {
searchState.inputElement().placeholder = searchState.inputElement().origPlaceholder;
});

// Push and pop states are used to add search results to the browser
// history.
if (browserSupportsHistoryApi()) {
// Store the previous <title> so we can revert back to it later.
const previousTitle = document.title;

window.addEventListener("popstate", e => {
const params = searchState.getQueryStringParams();
// Revert to the previous title manually since the History
// API ignores the title parameter.
document.title = previousTitle;
// When browsing forward to search results the previous
// search will be repeated, so the currentResults are
// cleared to ensure the search is successful.
currentResults = null;
// Synchronize search bar with query string state and
// perform the search. This will empty the bar if there's
// nothing there, which lets you really go back to a
// previous state with nothing in the bar.
if (params.search !== undefined) {
searchState.inputElement().value = params.search;
// Some browsers fire "onpopstate" for every page load
// (Chrome), while others fire the event only when actually
// popping a state (Firefox), which is why search() is
// called both here and at the end of the startSearch()
// function.
e.preventDefault();
search();
} else {
// When browsing back from search results the main page
// visibility must be reset.
searchState.hideResults();
}
});
}

// This is required in firefox to avoid this problem: Navigating to a search result
// with the keyboard, hitting enter, and then hitting back would take you back to
// the doc page, rather than the search that should overlay it.
// This was an interaction between the back-forward cache and our handlers
// that try to sync state between the URL and the search input. To work around it,
// do a small amount of re-init on page show.
window.onpageshow = () => {
const qSearch = searchState.getQueryStringParams().search;
if (qSearch !== undefined) {
if (searchState.inputElement().value === "") {
searchState.inputElement().value = qSearch;
}
search();
}
};
}

function updateCrate(ev) {
Expand Down

0 comments on commit 27f875a

Please sign in to comment.