Skip to content

Commit

Permalink
Auto merge of #92570 - jsha:rustdoc-search-refactor, r=GuillaumeGomez
Browse files Browse the repository at this point in the history
Simplify rustdoc search test

Previously, rustdoc search attempted to parse search.js and extract out only certain methods and variables.

This change makes search.js and search-index.js loadable as [CommonJS modules](https://nodejs.org/api/modules.html#modules-commonjs-modules), so they can be loaded directly.

As part of that change, I had to separate execSearch from interacting with the DOM. This wound up being a nice cleanup that made more explicit what inputs it was taking.

I removed search.js' dependency on storage.js by moving hasOwnPropertyRustdoc directly into search.js, and replacing onEach with forEach in a path that is called by the tester.

r? `@GuillaumeGomez`

Demo: https://rustdoc.crud.net/jsha/rustdoc-search-refactor/std/?search=foo
  • Loading branch information
bors committed May 17, 2022
2 parents 00755e4 + 4539794 commit 4c5f6e6
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 313 deletions.
8 changes: 7 additions & 1 deletion src/librustdoc/html/render/write_shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,13 @@ pub(super) fn write_shared(
write_crate("search-index.js", &|| {
let mut v = String::from("var searchIndex = JSON.parse('{\\\n");
v.push_str(&all_indexes.join(",\\\n"));
v.push_str("\\\n}');\nif (window.initSearch) {window.initSearch(searchIndex)};");
v.push_str(
r#"\
}');
if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)};
if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
"#,
);
Ok(v.into_bytes())
})?;

Expand Down
112 changes: 66 additions & 46 deletions src/librustdoc/html/static/js/search.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* global addClass, getNakedUrl, getSettingValue, hasOwnPropertyRustdoc, initSearch, onEach */
/* global onEachLazy, removeClass, searchState, browserSupportsHistoryApi */
/* global addClass, getNakedUrl, getSettingValue */
/* global onEachLazy, removeClass, searchState, browserSupportsHistoryApi, exports */

"use strict";

Expand Down Expand Up @@ -38,6 +38,11 @@ const itemTypes = [
// used for special search precedence
const TY_PRIMITIVE = itemTypes.indexOf("primitive");
const TY_KEYWORD = itemTypes.indexOf("keyword");
const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../";

function hasOwnPropertyRustdoc(obj, property) {
return Object.prototype.hasOwnProperty.call(obj, property);
}

// In the search display, allows to switch between tabs.
function printTab(nb) {
Expand Down Expand Up @@ -106,7 +111,7 @@ function levenshtein(s1, s2) {
return s1_len + s2_len;
}

window.initSearch = rawSearchIndex => {
function initSearch(rawSearchIndex) {
const MAX_LEV_DISTANCE = 3;
const MAX_RESULTS = 200;
const GENERICS_DATA = 2;
Expand All @@ -120,15 +125,6 @@ window.initSearch = rawSearchIndex => {
let searchIndex;
let currentResults;
const ALIASES = Object.create(null);
const params = searchState.getQueryStringParams();

// Populate search bar with query string search term when provided,
// but only if the input bar is empty. This avoid the obnoxious issue
// where you start trying to do a search, and the index loads, and
// suddenly your search is gone!
if (searchState.input.value === "") {
searchState.input.value = params.search || "";
}

function isWhitespace(c) {
return " \t\n\r".indexOf(c) !== -1;
Expand Down Expand Up @@ -726,10 +722,11 @@ window.initSearch = rawSearchIndex => {
* @param {ParsedQuery} parsedQuery - The parsed user query
* @param {Object} searchWords - The list of search words to query against
* @param {Object} [filterCrates] - Crate to search in if defined
* @param {Object} [currentCrate] - Current crate, to rank results from this crate higher
*
* @return {ResultsTable}
*/
function execQuery(parsedQuery, searchWords, filterCrates) {
function execQuery(parsedQuery, searchWords, filterCrates, currentCrate) {
const results_others = {}, results_in_args = {}, results_returned = {};

function transformResults(results) {
Expand Down Expand Up @@ -761,7 +758,7 @@ window.initSearch = rawSearchIndex => {
return out;
}

function sortResults(results, isType) {
function sortResults(results, isType, preferredCrate) {
const userQuery = parsedQuery.userQuery;
const ar = [];
for (const entry in results) {
Expand Down Expand Up @@ -796,9 +793,9 @@ window.initSearch = rawSearchIndex => {
return a - b;
}

// sort by crate (non-current crate goes later)
a = (aaa.item.crate !== window.currentCrate);
b = (bbb.item.crate !== window.currentCrate);
// sort by crate (current crate comes first)
a = (aaa.item.crate !== preferredCrate);
b = (bbb.item.crate !== preferredCrate);
if (a !== b) {
return a - b;
}
Expand Down Expand Up @@ -1178,7 +1175,7 @@ window.initSearch = rawSearchIndex => {
};
}

function handleAliases(ret, query, filterCrates) {
function handleAliases(ret, query, filterCrates, currentCrate) {
const lowerQuery = query.toLowerCase();
// We separate aliases and crate aliases because we want to have current crate
// aliases to be before the others in the displayed results.
Expand All @@ -1194,7 +1191,7 @@ window.initSearch = rawSearchIndex => {
} else {
Object.keys(ALIASES).forEach(crate => {
if (ALIASES[crate][lowerQuery]) {
const pushTo = crate === window.currentCrate ? crateAliases : aliases;
const pushTo = crate === currentCrate ? crateAliases : aliases;
const query_aliases = ALIASES[crate][lowerQuery];
for (const alias of query_aliases) {
pushTo.push(createAliasFromItem(searchIndex[alias]));
Expand Down Expand Up @@ -1226,8 +1223,9 @@ window.initSearch = rawSearchIndex => {
ret.others.pop();
}
};
onEach(aliases, pushFunc);
onEach(crateAliases, pushFunc);

aliases.forEach(pushFunc);
crateAliases.forEach(pushFunc);
}

/**
Expand Down Expand Up @@ -1444,11 +1442,11 @@ window.initSearch = rawSearchIndex => {
}

const ret = createQueryResults(
sortResults(results_in_args, true),
sortResults(results_returned, true),
sortResults(results_others, false),
sortResults(results_in_args, true, currentCrate),
sortResults(results_returned, true, currentCrate),
sortResults(results_others, false, currentCrate),
parsedQuery);
handleAliases(ret, parsedQuery.original.replace(/"/g, ""), filterCrates);
handleAliases(ret, parsedQuery.original.replace(/"/g, ""), filterCrates, currentCrate);
if (parsedQuery.error !== null && ret.others.length !== 0) {
// It means some doc aliases were found so let's "remove" the error!
ret.query.error = null;
Expand Down Expand Up @@ -1521,18 +1519,18 @@ window.initSearch = rawSearchIndex => {

if (type === "mod") {
displayPath = path + "::";
href = window.rootPath + path.replace(/::/g, "/") + "/" +
name + "/index.html";
href = ROOT_PATH + path.replace(/::/g, "/") + "/" +
name + "/index.html";
} else if (type === "import") {
displayPath = item.path + "::";
href = window.rootPath + item.path.replace(/::/g, "/") + "/index.html#reexport." + name;
href = ROOT_PATH + item.path.replace(/::/g, "/") + "/index.html#reexport." + name;
} else if (type === "primitive" || type === "keyword") {
displayPath = "";
href = window.rootPath + path.replace(/::/g, "/") +
"/" + type + "." + name + ".html";
href = ROOT_PATH + path.replace(/::/g, "/") +
"/" + type + "." + name + ".html";
} else if (type === "externcrate") {
displayPath = "";
href = window.rootPath + name + "/index.html";
href = ROOT_PATH + name + "/index.html";
} else if (item.parent !== undefined) {
const myparent = item.parent;
let anchor = "#" + type + "." + name;
Expand All @@ -1555,14 +1553,14 @@ window.initSearch = rawSearchIndex => {
} else {
displayPath = path + "::" + myparent.name + "::";
}
href = window.rootPath + path.replace(/::/g, "/") +
"/" + pageType +
"." + pageName +
".html" + anchor;
href = ROOT_PATH + path.replace(/::/g, "/") +
"/" + pageType +
"." + pageName +
".html" + anchor;
} else {
displayPath = item.path + "::";
href = window.rootPath + item.path.replace(/::/g, "/") +
"/" + type + "." + name + ".html";
href = ROOT_PATH + item.path.replace(/::/g, "/") +
"/" + type + "." + name + ".html";
}
return [displayPath, href];
}
Expand Down Expand Up @@ -1835,7 +1833,7 @@ window.initSearch = rawSearchIndex => {
}

showResults(
execQuery(query, searchWords, filterCrates),
execQuery(query, searchWords, filterCrates, window.currentCrate),
params.go_to_first,
filterCrates);
}
Expand Down Expand Up @@ -2015,6 +2013,16 @@ window.initSearch = rawSearchIndex => {
}

function registerSearchEvents() {
const params = searchState.getQueryStringParams();

// Populate search bar with query string search term when provided,
// but only if the input bar is empty. This avoid the obnoxious issue
// where you start trying to do a search, and the index loads, and
// suddenly your search is gone!
if (searchState.input.value === "") {
searchState.input.value = params.search || "";
}

const searchAfter500ms = () => {
searchState.clearInputTimeout();
if (searchState.input.value.length === 0) {
Expand Down Expand Up @@ -2167,20 +2175,32 @@ window.initSearch = rawSearchIndex => {
* @type {Array<string>}
*/
const searchWords = buildIndex(rawSearchIndex);
registerSearchEvents();

function runSearchIfNeeded() {
if (typeof window !== "undefined") {
registerSearchEvents();
// If there's a search term in the URL, execute the search now.
if (searchState.getQueryStringParams().search) {
if (window.searchState.getQueryStringParams().search) {
search();
}
}

runSearchIfNeeded();
};
if (typeof exports !== "undefined") {
exports.initSearch = initSearch;
exports.execQuery = execQuery;
exports.parseQuery = parseQuery;
}
return searchWords;
}

if (window.searchIndex !== undefined) {
initSearch(window.searchIndex);
if (typeof window !== "undefined") {
window.initSearch = initSearch;
if (window.searchIndex !== undefined) {
initSearch(window.searchIndex);
}
} else {
// Running in Node, not a browser. Run initSearch just to produce the
// exports.
initSearch({});
}


})();
5 changes: 0 additions & 5 deletions src/librustdoc/html/static/js/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,6 @@ function onEachLazy(lazyArray, func, reversed) {
reversed);
}

// eslint-disable-next-line no-unused-vars
function hasOwnPropertyRustdoc(obj, property) {
return Object.prototype.hasOwnProperty.call(obj, property);
}

function updateLocalStorage(name, value) {
try {
window.localStorage.setItem("rustdoc-" + name, value);
Expand Down
Loading

0 comments on commit 4c5f6e6

Please sign in to comment.