1
Fork 0

Rollup merge of #92735 - GuillaumeGomez:crate-filter-url-param, r=jsha

Add crate filter parameter in URL

Fixes #92621.

r? `@jsha`
This commit is contained in:
Matthias Krüger 2022-02-04 14:58:56 +01:00 committed by GitHub
commit f2721fab23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 140 additions and 58 deletions

View file

@ -54,7 +54,6 @@ function resourcePath(basename, extension) {
return getVar("root-path") + basename + getVar("resource-suffix") + extension; return getVar("root-path") + basename + getVar("resource-suffix") + extension;
} }
(function () { (function () {
window.rootPath = getVar("root-path"); window.rootPath = getVar("root-path");
window.currentCrate = getVar("current-crate"); window.currentCrate = getVar("current-crate");
@ -232,7 +231,7 @@ function hideThemeButtonState() {
document.title = searchState.titleBeforeSearch; document.title = searchState.titleBeforeSearch;
// We also remove the query parameter from the URL. // We also remove the query parameter from the URL.
if (searchState.browserSupportsHistoryApi()) { if (searchState.browserSupportsHistoryApi()) {
history.replaceState("", window.currentCrate + " - Rust", history.replaceState(null, window.currentCrate + " - Rust",
getNakedUrl() + window.location.hash); getNakedUrl() + window.location.hash);
} }
}, },
@ -246,18 +245,6 @@ function hideThemeButtonState() {
}); });
return params; return params;
}, },
putBackSearch: function(search_input) {
var search = searchState.outputElement();
if (search_input.value !== "" && hasClass(search, "hidden")) {
searchState.showResults(search);
if (searchState.browserSupportsHistoryApi()) {
var extra = "?search=" + encodeURIComponent(search_input.value);
history.replaceState(search_input.value, "",
getNakedUrl() + extra + window.location.hash);
}
document.title = searchState.title;
}
},
browserSupportsHistoryApi: function() { browserSupportsHistoryApi: function() {
return window.history && typeof window.history.pushState === "function"; return window.history && typeof window.history.pushState === "function";
}, },
@ -282,14 +269,10 @@ function hideThemeButtonState() {
} }
search_input.addEventListener("focus", function() { search_input.addEventListener("focus", function() {
searchState.putBackSearch(this); search_input.origPlaceholder = search_input.placeholder;
search_input.origPlaceholder = searchState.input.placeholder;
search_input.placeholder = "Type your search here."; search_input.placeholder = "Type your search here.";
loadSearch(); loadSearch();
}); });
search_input.addEventListener("blur", function() {
search_input.placeholder = searchState.input.origPlaceholder;
});
if (search_input.value != '') { if (search_input.value != '') {
loadSearch(); loadSearch();
@ -330,7 +313,7 @@ function hideThemeButtonState() {
var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1); var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
if (searchState.browserSupportsHistoryApi()) { if (searchState.browserSupportsHistoryApi()) {
// `window.location.search`` contains all the query parameters, not just `search`. // `window.location.search`` contains all the query parameters, not just `search`.
history.replaceState(hash, "", history.replaceState(null, "",
getNakedUrl() + window.location.search + "#" + hash); getNakedUrl() + window.location.search + "#" + hash);
} }
elem = document.getElementById(hash); elem = document.getElementById(hash);

View file

@ -1,5 +1,5 @@
/* global addClass, getNakedUrl, getSettingValue, hasOwnPropertyRustdoc, initSearch, onEach */ /* global addClass, getNakedUrl, getSettingValue, hasOwnPropertyRustdoc, initSearch, onEach */
/* global onEachLazy, removeClass, searchState, updateLocalStorage */ /* global onEachLazy, removeClass, searchState, hasClass */
(function() { (function() {
// This mapping table should match the discriminants of // This mapping table should match the discriminants of
@ -133,6 +133,39 @@ window.initSearch = function(rawSearchIndex) {
searchState.input.value = params.search || ""; searchState.input.value = params.search || "";
} }
/**
* Build an URL with search parameters.
*
* @param {string} search - The current search being performed.
* @param {string|null} filterCrates - The current filtering crate (if any).
* @return {string}
*/
function buildUrl(search, filterCrates) {
var extra = "?search=" + encodeURIComponent(search);
if (filterCrates !== null) {
extra += "&filter-crate=" + encodeURIComponent(filterCrates);
}
return getNakedUrl() + extra + window.location.hash;
}
/**
* Return the filtering crate or `null` if there is none.
*
* @return {string|null}
*/
function getFilterCrates() {
var elem = document.getElementById("crate-search");
if (elem &&
elem.value !== "All crates" &&
hasOwnPropertyRustdoc(rawSearchIndex, elem.value))
{
return elem.value;
}
return null;
}
/** /**
* Executes the query and returns a list of results for each results tab. * Executes the query and returns a list of results for each results tab.
* @param {Object} query - The user query * @param {Object} query - The user query
@ -595,7 +628,7 @@ window.initSearch = function(rawSearchIndex) {
// aliases to be before the others in the displayed results. // aliases to be before the others in the displayed results.
var aliases = []; var aliases = [];
var crateAliases = []; var crateAliases = [];
if (filterCrates !== undefined) { if (filterCrates !== null) {
if (ALIASES[filterCrates] && ALIASES[filterCrates][query.search]) { if (ALIASES[filterCrates] && ALIASES[filterCrates][query.search]) {
var query_aliases = ALIASES[filterCrates][query.search]; var query_aliases = ALIASES[filterCrates][query.search];
var len = query_aliases.length; var len = query_aliases.length;
@ -694,7 +727,7 @@ window.initSearch = function(rawSearchIndex) {
{ {
val = extractGenerics(val.substr(1, val.length - 2)); val = extractGenerics(val.substr(1, val.length - 2));
for (i = 0; i < nSearchWords; ++i) { for (i = 0; i < nSearchWords; ++i) {
if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) { if (filterCrates !== null && searchIndex[i].crate !== filterCrates) {
continue; continue;
} }
in_args = findArg(searchIndex[i], val, true, typeFilter); in_args = findArg(searchIndex[i], val, true, typeFilter);
@ -725,7 +758,7 @@ window.initSearch = function(rawSearchIndex) {
var output = extractGenerics(parts[1]); var output = extractGenerics(parts[1]);
for (i = 0; i < nSearchWords; ++i) { for (i = 0; i < nSearchWords; ++i) {
if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) { if (filterCrates !== null && searchIndex[i].crate !== filterCrates) {
continue; continue;
} }
var type = searchIndex[i].type; var type = searchIndex[i].type;
@ -781,7 +814,7 @@ window.initSearch = function(rawSearchIndex) {
var lev, j; var lev, j;
for (j = 0; j < nSearchWords; ++j) { for (j = 0; j < nSearchWords; ++j) {
ty = searchIndex[j]; ty = searchIndex[j];
if (!ty || (filterCrates !== undefined && ty.crate !== filterCrates)) { if (!ty || (filterCrates !== null && ty.crate !== filterCrates)) {
continue; continue;
} }
var lev_add = 0; var lev_add = 0;
@ -1279,17 +1312,6 @@ window.initSearch = function(rawSearchIndex) {
}; };
} }
function getFilterCrates() {
var elem = document.getElementById("crate-search");
if (elem && elem.value !== "All crates" &&
hasOwnPropertyRustdoc(rawSearchIndex, elem.value))
{
return elem.value;
}
return undefined;
}
/** /**
* Perform a search based on the current state of the search input element * Perform a search based on the current state of the search input element
* and display the results. * and display the results.
@ -1309,27 +1331,34 @@ window.initSearch = function(rawSearchIndex) {
} }
if (!forced && query.id === currentResults) { if (!forced && query.id === currentResults) {
if (query.query.length > 0) { if (query.query.length > 0) {
searchState.putBackSearch(searchState.input); putBackSearch();
} }
return; return;
} }
var filterCrates = getFilterCrates();
// In case we have no information about the saved crate and there is a URL query parameter,
// we override it with the URL query parameter.
if (filterCrates === null && params["filter-crate"] !== undefined) {
filterCrates = params["filter-crate"];
}
// Update document title to maintain a meaningful browser history // Update document title to maintain a meaningful browser history
searchState.title = "Results for " + query.query + " - Rust"; searchState.title = "Results for " + query.query + " - Rust";
// Because searching is incremental by character, only the most // Because searching is incremental by character, only the most
// recent search query is added to the browser history. // recent search query is added to the browser history.
if (searchState.browserSupportsHistoryApi()) { if (searchState.browserSupportsHistoryApi()) {
var newURL = getNakedUrl() + "?search=" + encodeURIComponent(query.raw) + var newURL = buildUrl(query.raw, filterCrates);
window.location.hash;
if (!history.state && !params.search) { if (!history.state && !params.search) {
history.pushState(query, "", newURL); history.pushState(null, "", newURL);
} else { } else {
history.replaceState(query, "", newURL); history.replaceState(null, "", newURL);
} }
} }
var filterCrates = getFilterCrates();
showResults(execSearch(query, searchWords, filterCrates), showResults(execSearch(query, searchWords, filterCrates),
params["go_to_first"], filterCrates); params["go_to_first"], filterCrates);
} }
@ -1495,12 +1524,28 @@ window.initSearch = function(rawSearchIndex) {
search(); search();
} }
function putBackSearch() {
var search_input = searchState.input;
if (!searchState.input) {
return;
}
var search = searchState.outputElement();
if (search_input.value !== "" && hasClass(search, "hidden")) {
searchState.showResults(search);
if (searchState.browserSupportsHistoryApi()) {
history.replaceState(null, "",
buildUrl(search_input.value, getFilterCrates()));
}
document.title = searchState.title;
}
}
function registerSearchEvents() { function registerSearchEvents() {
var searchAfter500ms = function() { var searchAfter500ms = function() {
searchState.clearInputTimeout(); searchState.clearInputTimeout();
if (searchState.input.value.length === 0) { if (searchState.input.value.length === 0) {
if (searchState.browserSupportsHistoryApi()) { if (searchState.browserSupportsHistoryApi()) {
history.replaceState("", window.currentCrate + " - Rust", history.replaceState(null, window.currentCrate + " - Rust",
getNakedUrl() + window.location.hash); getNakedUrl() + window.location.hash);
} }
searchState.hideResults(); searchState.hideResults();
@ -1567,6 +1612,14 @@ window.initSearch = function(rawSearchIndex) {
} }
}); });
searchState.input.addEventListener("focus", function() {
putBackSearch();
});
searchState.input.addEventListener("blur", function() {
searchState.input.placeholder = searchState.input.origPlaceholder;
});
// Push and pop states are used to add search results to the browser // Push and pop states are used to add search results to the browser
// history. // history.
if (searchState.browserSupportsHistoryApi()) { if (searchState.browserSupportsHistoryApi()) {
@ -1619,7 +1672,16 @@ window.initSearch = function(rawSearchIndex) {
} }
function updateCrate(ev) { function updateCrate(ev) {
updateLocalStorage("rustdoc-saved-filter-crate", ev.target.value); if (ev.target.value === "All crates") {
// If we don't remove it from the URL, it'll be picked up again by the search.
var params = searchState.getQueryStringParams();
var query = searchState.input.value.trim();
if (!history.state && !params.search) {
history.pushState(null, "", buildUrl(query, null));
} else {
history.replaceState(null, "", buildUrl(query, null));
}
}
// In case you "cut" the entry from the search input, then change the crate filter // In case you "cut" the entry from the search input, then change the crate filter
// before paste back the previous search, you get the old search results without // before paste back the previous search, you get the old search results without
// the filter. To prevent this, we need to remove the previous results. // the filter. To prevent this, we need to remove the previous results.
@ -1629,10 +1691,15 @@ window.initSearch = function(rawSearchIndex) {
searchWords = buildIndex(rawSearchIndex); searchWords = buildIndex(rawSearchIndex);
registerSearchEvents(); registerSearchEvents();
function runSearchIfNeeded() {
// If there's a search term in the URL, execute the search now. // If there's a search term in the URL, execute the search now.
if (searchState.getQueryStringParams().search) { if (searchState.getQueryStringParams().search) {
search(); search();
} }
}
runSearchIfNeeded();
}; };
if (window.searchIndex !== undefined) { if (window.searchIndex !== undefined) {

View file

@ -4,7 +4,7 @@
(function () { (function () {
function changeSetting(settingName, value) { function changeSetting(settingName, value) {
updateLocalStorage("rustdoc-" + settingName, value); updateLocalStorage(settingName, value);
switch (settingName) { switch (settingName) {
case "theme": case "theme":

View file

@ -82,11 +82,11 @@ function toggleSidebar() {
if (child.innerText === ">") { if (child.innerText === ">") {
sidebar.classList.add("expanded"); sidebar.classList.add("expanded");
child.innerText = "<"; child.innerText = "<";
updateLocalStorage("rustdoc-source-sidebar-show", "true"); updateLocalStorage("source-sidebar-show", "true");
} else { } else {
sidebar.classList.remove("expanded"); sidebar.classList.remove("expanded");
child.innerText = ">"; child.innerText = ">";
updateLocalStorage("rustdoc-source-sidebar-show", "false"); updateLocalStorage("source-sidebar-show", "false");
} }
} }
@ -97,7 +97,7 @@ function createSidebarToggle() {
var inner = document.createElement("div"); var inner = document.createElement("div");
if (getCurrentValue("rustdoc-source-sidebar-show") === "true") { if (getCurrentValue("source-sidebar-show") === "true") {
inner.innerText = "<"; inner.innerText = "<";
} else { } else {
inner.innerText = ">"; inner.innerText = ">";
@ -120,7 +120,7 @@ function createSourceSidebar() {
var sidebar = document.createElement("div"); var sidebar = document.createElement("div");
sidebar.id = "source-sidebar"; sidebar.id = "source-sidebar";
if (getCurrentValue("rustdoc-source-sidebar-show") !== "true") { if (getCurrentValue("source-sidebar-show") !== "true") {
container.classList.remove("expanded"); container.classList.remove("expanded");
} else { } else {
container.classList.add("expanded"); container.classList.add("expanded");

View file

@ -15,7 +15,7 @@ var settingsDataset = (function () {
})(); })();
function getSettingValue(settingName) { function getSettingValue(settingName) {
var current = getCurrentValue('rustdoc-' + settingName); var current = getCurrentValue(settingName);
if (current !== null) { if (current !== null) {
return current; return current;
} }
@ -106,7 +106,7 @@ function hasOwnPropertyRustdoc(obj, property) {
function updateLocalStorage(name, value) { function updateLocalStorage(name, value) {
try { try {
window.localStorage.setItem(name, value); window.localStorage.setItem("rustdoc-" + name, value);
} catch(e) { } catch(e) {
// localStorage is not accessible, do nothing // localStorage is not accessible, do nothing
} }
@ -114,7 +114,7 @@ function updateLocalStorage(name, value) {
function getCurrentValue(name) { function getCurrentValue(name) {
try { try {
return window.localStorage.getItem(name); return window.localStorage.getItem("rustdoc-" + name);
} catch(e) { } catch(e) {
return null; return null;
} }
@ -127,7 +127,7 @@ function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
// If this new value comes from a system setting or from the previously // If this new value comes from a system setting or from the previously
// saved theme, no need to save it. // saved theme, no need to save it.
if (saveTheme) { if (saveTheme) {
updateLocalStorage("rustdoc-theme", newTheme); updateLocalStorage("theme", newTheme);
} }
if (styleElem.href === newHref) { if (styleElem.href === newHref) {
@ -158,7 +158,7 @@ function useSystemTheme(value) {
value = true; value = true;
} }
updateLocalStorage("rustdoc-use-system-theme", value); updateLocalStorage("use-system-theme", value);
// update the toggle if we're on the settings page // update the toggle if we're on the settings page
var toggle = document.getElementById("use-system-theme"); var toggle = document.getElementById("use-system-theme");
@ -231,7 +231,7 @@ if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) {
if (getSettingValue("use-system-theme") === null if (getSettingValue("use-system-theme") === null
&& getSettingValue("preferred-dark-theme") === null && getSettingValue("preferred-dark-theme") === null
&& darkThemes.indexOf(localStoredTheme) >= 0) { && darkThemes.indexOf(localStoredTheme) >= 0) {
updateLocalStorage("rustdoc-preferred-dark-theme", localStoredTheme); updateLocalStorage("preferred-dark-theme", localStoredTheme);
} }
// call the function to initialize the theme at least once! // call the function to initialize the theme at least once!

View file

@ -11,8 +11,38 @@ wait-for: "#crate-search"
click: "#crate-search" click: "#crate-search"
// We select "lib2" option then press enter to change the filter. // We select "lib2" option then press enter to change the filter.
press-key: "ArrowDown" press-key: "ArrowDown"
press-key: "ArrowDown"
press-key: "Enter" press-key: "Enter"
// Waiting for the search results to appear... // Waiting for the search results to appear...
wait-for: "#titles" wait-for: "#titles"
// We check that there is no more "test_docs" appearing. // We check that there is no more "test_docs" appearing.
assert-false: "#results .externcrate" assert-false: "#results .externcrate"
// We also check that "lib2" is the filter crate.
assert-property: ("#crate-search", {"value": "lib2"})
// Now we check that leaving the search results and putting them back keeps the
// crate filtering.
press-key: "Escape"
wait-for: 100
assert-css: ("#main-content", {"display": "block"})
focus: ".search-input"
wait-for: 100
assert-css: ("#main-content", {"display": "none"})
// We check that there is no more "test_docs" appearing.
assert-false: "#results .externcrate"
assert-property: ("#crate-search", {"value": "lib2"})
// Selecting back "All crates"
click: "#crate-search"
press-key: "ArrowUp"
press-key: "ArrowUp"
press-key: "Enter"
// Waiting for the search results to appear...
wait-for: "#titles"
assert-property: ("#crate-search", {"value": "All crates"})
// Checking that the URL parameter is taken into account for crate filtering.
goto: file://|DOC_PATH|/test_docs/index.html?search=test&filter-crate=lib2
wait-for: "#crate-search"
assert-property: ("#crate-search", {"value": "lib2"})
assert-false: "#results .externcrate"

View file

@ -357,6 +357,8 @@ function runChecks(testFile, loaded, index) {
var testFileContent = readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;'; var testFileContent = readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;';
if (testFileContent.indexOf("FILTER_CRATE") !== -1) { if (testFileContent.indexOf("FILTER_CRATE") !== -1) {
testFileContent += "exports.FILTER_CRATE = FILTER_CRATE;"; testFileContent += "exports.FILTER_CRATE = FILTER_CRATE;";
} else {
testFileContent += "exports.FILTER_CRATE = null;";
} }
var loadedFile = loadContent(testFileContent); var loadedFile = loadContent(testFileContent);