Skip to content

Commit 95d652e

Browse files
committed
Consolidate search-related vars and functions.
This allows sharing across main.js and search.js without exporting too many symbols into the global namespace.
1 parent 276ee6f commit 95d652e

File tree

2 files changed

+167
-175
lines changed

2 files changed

+167
-175
lines changed

src/librustdoc/html/static/main.js

Lines changed: 128 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,6 @@ function getSearchInput() {
8080
return document.getElementsByClassName("search-input")[0];
8181
}
8282

83-
function getSearchElement() {
84-
return document.getElementById("search");
85-
}
86-
8783
var THEME_PICKER_ELEMENT_ID = "theme-picker";
8884
var THEMES_ELEMENT_ID = "theme-choices";
8985

@@ -172,30 +168,123 @@ function hideThemeButtonState() {
172168
(function() {
173169
"use strict";
174170

175-
var disableShortcuts = getSettingValue("disable-shortcuts") === "true";
176-
window.search_input = getSearchInput();
177-
var searchTimeout = null;
178-
var toggleAllDocsId = "toggle-all-docs";
171+
window.searchState = {
172+
loadingText: "Loading search results...",
173+
input: getSearchInput(),
174+
outputElement: function() {
175+
return document.getElementById("search");
176+
},
177+
title: null,
178+
titleBeforeSearch: document.title,
179+
timeout: null,
180+
// On the search screen, so you remain on the last tab you opened.
181+
//
182+
// 0 for "In Names"
183+
// 1 for "In Parameters"
184+
// 2 for "In Return Types"
185+
currentTab: 0,
186+
mouseMovedAfterSearch: true,
187+
clearInputTimeout: function() {
188+
if (searchState.timeout !== null) {
189+
clearTimeout(searchState.timeout);
190+
searchState.timeout = null;
191+
}
192+
},
193+
showResults: function(search) {
194+
if (search === null || typeof search === 'undefined') {
195+
search = searchState.outputElement();
196+
}
197+
addClass(main, "hidden");
198+
removeClass(search, "hidden");
199+
searchState.mouseMovedAfterSearch = false;
200+
document.title = searchState.title;
201+
},
202+
hideResults: function(search) {
203+
if (search === null || typeof search === 'undefined') {
204+
search = searchState.outputElement();
205+
}
206+
addClass(search, "hidden");
207+
removeClass(main, "hidden");
208+
document.title = searchState.titleBeforeSearch;
209+
// We also remove the query parameter from the URL.
210+
if (searchState.browserSupportsHistoryApi()) {
211+
history.replaceState("", window.currentCrate + " - Rust",
212+
getNakedUrl() + window.location.hash);
213+
}
214+
},
215+
getQueryStringParams: function() {
216+
var params = {};
217+
window.location.search.substring(1).split("&").
218+
map(function(s) {
219+
var pair = s.split("=");
220+
params[decodeURIComponent(pair[0])] =
221+
typeof pair[1] === "undefined" ? null : decodeURIComponent(pair[1]);
222+
});
223+
return params;
224+
},
225+
putBackSearch: function(search_input) {
226+
var search = searchState.outputElement();
227+
if (search_input.value !== "" && hasClass(search, "hidden")) {
228+
searchState.showResults(search);
229+
if (searchState.browserSupportsHistoryApi()) {
230+
var extra = "?search=" + encodeURIComponent(search_input.value);
231+
history.replaceState(search_input.value, "",
232+
getNakedUrl() + extra + window.location.hash);
233+
}
234+
document.title = searchState.title;
235+
}
236+
},
237+
browserSupportsHistoryApi: function() {
238+
return window.history && typeof window.history.pushState === "function";
239+
},
240+
setupLoader: function() {
241+
function loadScript(url) {
242+
var script = document.createElement('script');
243+
script.src = url;
244+
document.head.append(script);
245+
}
179246

180-
// On the search screen, so you remain on the last tab you opened.
181-
//
182-
// 0 for "In Names"
183-
// 1 for "In Parameters"
184-
// 2 for "In Return Types"
185-
window.currentTab = 0;
247+
var searchLoaded = false;
248+
function loadSearch() {
249+
if (!searchLoaded) {
250+
searchLoaded = true;
251+
loadScript(window.searchJS);
252+
}
253+
}
186254

187-
window.mouseMovedAfterSearch = true;
255+
// `crates{version}.js` should always be loaded before this script, so we can use it safely.
256+
addSearchOptions(window.ALL_CRATES);
257+
addSidebarCrates(window.ALL_CRATES);
188258

189-
var titleBeforeSearch = document.title;
190-
window.searchTitle = null;
259+
searchState.input.addEventListener("focus", function() {
260+
searchState.input.origPlaceholder = searchState.input.placeholder;
261+
searchState.input.placeholder = "Type your search here.";
262+
loadSearch();
263+
});
264+
searchState.input.addEventListener("blur", function() {
265+
searchState.input.placeholder = searchState.input.origPlaceholder;
266+
});
267+
searchState.input.removeAttribute('disabled');
191268

192-
window.clearInputTimeout = function() {
193-
if (searchTimeout !== null) {
194-
clearTimeout(searchTimeout);
195-
searchTimeout = null;
269+
var crateSearchDropDown = document.getElementById("crate-search");
270+
// `crateSearchDropDown` can be null in case there is only crate because in that case, the
271+
// crate filter dropdown is removed.
272+
if (crateSearchDropDown) {
273+
crateSearchDropDown.addEventListener("focus", loadSearch);
274+
}
275+
var params = searchState.getQueryStringParams();
276+
if (params.search !== undefined) {
277+
loadSearch();
196278
}
279+
},
197280
};
198281

282+
if (searchState.input) {
283+
searchState.input.onfocus = function() {
284+
searchState.putBackSearch(this);
285+
};
286+
}
287+
199288
function getPageId() {
200289
if (window.location.hash) {
201290
var tmp = window.location.hash.replace(/^#/, "");
@@ -237,61 +326,23 @@ function hideThemeButtonState() {
237326
document.getElementsByTagName("body")[0].style.marginTop = "";
238327
}
239328

240-
window.showSearchResults = function(search) {
241-
if (search === null || typeof search === 'undefined') {
242-
search = getSearchElement();
243-
}
244-
addClass(main, "hidden");
245-
removeClass(search, "hidden");
246-
mouseMovedAfterSearch = false;
247-
document.title = searchTitle;
248-
};
249-
250-
window.hideSearchResults = function(search) {
251-
if (search === null || typeof search === 'undefined') {
252-
search = getSearchElement();
253-
}
254-
addClass(search, "hidden");
255-
removeClass(main, "hidden");
256-
document.title = titleBeforeSearch;
257-
// We also remove the query parameter from the URL.
258-
if (browserSupportsHistoryApi()) {
259-
history.replaceState("", window.currentCrate + " - Rust",
260-
getNakedUrl() + window.location.hash);
261-
}
262-
};
263-
264-
window.getQueryStringParams = function() {
265-
var params = {};
266-
window.location.search.substring(1).split("&").
267-
map(function(s) {
268-
var pair = s.split("=");
269-
params[decodeURIComponent(pair[0])] =
270-
typeof pair[1] === "undefined" ? null : decodeURIComponent(pair[1]);
271-
});
272-
return params;
273-
};
274-
275-
window.browserSupportsHistoryApi = function() {
276-
return window.history && typeof window.history.pushState === "function";
277-
};
278-
279329
function isHidden(elem) {
280330
return elem.offsetHeight === 0;
281331
}
282332

333+
var toggleAllDocsId = "toggle-all-docs";
283334
var main = document.getElementById("main");
284335
var savedHash = "";
285336

286337
function handleHashes(ev) {
287338
var elem;
288-
var search = getSearchElement();
339+
var search = searchState.outputElement();
289340
if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
290341
// This block occurs when clicking on an element in the navbar while
291342
// in a search.
292-
hideSearchResults(search);
343+
searchState.hideResults(search);
293344
var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
294-
if (browserSupportsHistoryApi()) {
345+
if (searchState.browserSupportsHistoryApi()) {
295346
// `window.location.search`` contains all the query parameters, not just `search`.
296347
history.replaceState(hash, "",
297348
getNakedUrl() + window.location.search + "#" + hash);
@@ -432,18 +483,19 @@ function hideThemeButtonState() {
432483

433484
function handleEscape(ev) {
434485
var help = getHelpElement(false);
435-
var search = getSearchElement();
486+
var search = searchState.outputElement();
436487
if (hasClass(help, "hidden") === false) {
437488
displayHelp(false, ev, help);
438489
} else if (hasClass(search, "hidden") === false) {
439-
clearInputTimeout();
490+
searchState.clearInputTimeout();
440491
ev.preventDefault();
441-
hideSearchResults(search);
492+
searchState.hideResults(search);
442493
}
443494
defocusSearchBar();
444495
hideThemeButtonState();
445496
}
446497

498+
var disableShortcuts = getSettingValue("disable-shortcuts") === "true";
447499
function handleShortcut(ev) {
448500
// Don't interfere with browser shortcuts
449501
if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts === true) {
@@ -553,15 +605,17 @@ function hideThemeButtonState() {
553605
document.addEventListener("keypress", handleShortcut);
554606
document.addEventListener("keydown", handleShortcut);
555607

556-
document.addEventListener("mousemove", function() { mouseMovedAfterSearch = true; });
608+
document.addEventListener("mousemove", function() {
609+
searchState.mouseMovedAfterSearch = true;
610+
});
557611

558612
var handleSourceHighlight = (function() {
559613
var prev_line_id = 0;
560614

561615
var set_fragment = function(name) {
562616
var x = window.scrollX,
563617
y = window.scrollY;
564-
if (browserSupportsHistoryApi()) {
618+
if (searchState.browserSupportsHistoryApi()) {
565619
history.replaceState(null, null, "#" + name);
566620
highlightSourceLines();
567621
} else {
@@ -1366,34 +1420,11 @@ function hideThemeButtonState() {
13661420
};
13671421
});
13681422

1369-
window.putBackSearch = function(search_input) {
1370-
var search = getSearchElement();
1371-
if (search_input.value !== "" && hasClass(search, "hidden")) {
1372-
showSearchResults(search);
1373-
if (browserSupportsHistoryApi()) {
1374-
var extra = "?search=" + encodeURIComponent(search_input.value);
1375-
history.replaceState(search_input.value, "",
1376-
getNakedUrl() + extra + window.location.hash);
1377-
}
1378-
document.title = searchTitle;
1379-
}
1380-
};
1381-
1382-
function getSearchLoadingText() {
1383-
return "Loading search results...";
1384-
}
1385-
1386-
if (search_input) {
1387-
search_input.onfocus = function() {
1388-
putBackSearch(this);
1389-
};
1390-
}
1391-
1392-
var params = getQueryStringParams();
1423+
var params = searchState.getQueryStringParams();
13931424
if (params && params.search) {
1394-
var search = getSearchElement();
1395-
search.innerHTML = "<h3 style=\"text-align: center;\">" + getSearchLoadingText() + "</h3>";
1396-
showSearchResults(search);
1425+
var search = searchState.outputElement();
1426+
search.innerHTML = "<h3 style=\"text-align: center;\">" + searchState.loadingText + "</h3>";
1427+
searchState.showResults(search);
13971428
}
13981429

13991430
var sidebar_menu = document.getElementsByClassName("sidebar-menu")[0];
@@ -1509,55 +1540,14 @@ function hideThemeButtonState() {
15091540
container.appendChild(div_infos);
15101541

15111542
popup.appendChild(container);
1512-
insertAfter(popup, getSearchElement());
1543+
insertAfter(popup, searchState.outputElement());
15131544
// So that it's only built once and then it'll do nothing when called!
15141545
buildHelperPopup = function() {};
15151546
}
15161547

1517-
function loadScript(url) {
1518-
var script = document.createElement('script');
1519-
script.src = url;
1520-
document.head.append(script);
1521-
}
1522-
1523-
function setupSearchLoader() {
1524-
var searchLoaded = false;
1525-
function loadSearch() {
1526-
if (!searchLoaded) {
1527-
searchLoaded = true;
1528-
loadScript(window.searchJS);
1529-
}
1530-
}
1531-
1532-
// `crates{version}.js` should always be loaded before this script, so we can use it safely.
1533-
addSearchOptions(window.ALL_CRATES);
1534-
addSidebarCrates(window.ALL_CRATES);
1535-
1536-
search_input.addEventListener("focus", function() {
1537-
search_input.origPlaceholder = search_input.placeholder;
1538-
search_input.placeholder = "Type your search here.";
1539-
loadSearch();
1540-
});
1541-
search_input.addEventListener("blur", function() {
1542-
search_input.placeholder = search_input.origPlaceholder;
1543-
});
1544-
search_input.removeAttribute('disabled');
1545-
1546-
var crateSearchDropDown = document.getElementById("crate-search");
1547-
// `crateSearchDropDown` can be null in case there is only crate because in that case, the
1548-
// crate filter dropdown is removed.
1549-
if (crateSearchDropDown) {
1550-
crateSearchDropDown.addEventListener("focus", loadSearch);
1551-
}
1552-
var params = getQueryStringParams();
1553-
if (params.search !== undefined) {
1554-
loadSearch();
1555-
}
1556-
}
1557-
15581548
onHashChange(null);
15591549
window.onhashchange = onHashChange;
1560-
setupSearchLoader();
1550+
searchState.setupLoader();
15611551
}());
15621552

15631553
function copy_path(but) {

0 commit comments

Comments
 (0)