X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustdoc%2Fhtml%2Fstatic%2Fmain.js;h=3ffb72ba3ee8b645f85ee6400c176052214ad883;hb=0b1870e7b98f6319a38750c41738c3ad35f01a27;hp=ec8024ffca5294894206c0b6acdbd0d7456954aa;hpb=6163bfdcce6404c5d61d6ab441bf49a831082194;p=rust.git diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index ec8024ffca5..7e613220f2d 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1,9 +1,6 @@ -// From rust: -/* global ALIASES, currentCrate, rootPath */ - // Local js definitions: -/* global addClass, getCurrentValue, hasClass */ -/* global onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */ +/* global addClass, getSettingValue, hasClass */ +/* global onEach, onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */ /* global hideThemeButtonState, showThemeButtonState */ if (!String.prototype.startsWith) { @@ -40,6 +37,21 @@ if (!DOMTokenList.prototype.remove) { }; } +(function () { + var rustdocVars = document.getElementById("rustdoc-vars"); + if (rustdocVars) { + window.rootPath = rustdocVars.attributes["data-root-path"].value; + window.currentCrate = rustdocVars.attributes["data-current-crate"].value; + } + var sidebarVars = document.getElementById("sidebar-vars"); + if (sidebarVars) { + window.sidebarCurrent = { + name: sidebarVars.attributes["data-name"].value, + ty: sidebarVars.attributes["data-ty"].value, + relpath: sidebarVars.attributes["data-relpath"].value, + }; + } +}()); // Gets the human-readable string for the virtual-key code of the // given KeyboardEvent, ev. @@ -79,6 +91,11 @@ function getThemePickerElement() { return document.getElementById("theme-picker"); } +// Returns the current URL without any query parameter or hash. +function getNakedUrl() { + return window.location.href.split("?")[0].split("#")[0]; +} + // Sets the focus on the search bar at the top of the page function focusSearchBar() { getSearchInput().focus(); @@ -240,7 +257,9 @@ function defocusSearchBar() { hideSearchResults(search); var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1); if (browserSupportsHistoryApi()) { - history.replaceState(hash, "", "?search=#" + hash); + // `window.location.search`` contains all the query parameters, not just `search`. + history.replaceState(hash, "", + getNakedUrl() + window.location.search + "#" + hash); } elem = document.getElementById(hash); if (elem) { @@ -565,7 +584,7 @@ function defocusSearchBar() { var i, match, url = document.location.href, stripped = "", - len = rootPath.match(/\.\.\//g).length + 1; + len = window.rootPath.match(/\.\.\//g).length + 1; for (i = 0; i < len; ++i) { match = url.match(/\/[^\/]*$/); @@ -648,8 +667,7 @@ function defocusSearchBar() { */ function execQuery(query, searchWords, filterCrates) { function itemTypeFromName(typename) { - var length = itemTypes.length; - for (var i = 0; i < length; ++i) { + for (var i = 0, len = itemTypes.length; i < len; ++i) { if (itemTypes[i] === typename) { return i; } @@ -667,8 +685,7 @@ function defocusSearchBar() { function transformResults(results, isType) { var out = []; - var length = results.length; - for (var i = 0; i < length; ++i) { + for (var i = 0, len = results.length; i < len; ++i) { if (results[i].id > -1) { var obj = searchIndex[results[i].id]; obj.lev = results[i].lev; @@ -697,11 +714,11 @@ function defocusSearchBar() { } } results = ar; - var i; - var nresults = results.length; - for (i = 0; i < nresults; ++i) { - results[i].word = searchWords[results[i].id]; - results[i].item = searchIndex[results[i].id] || {}; + var i, len, result; + for (i = 0, len = results.length; i < len; ++i) { + result = results[i]; + result.word = searchWords[result.id]; + result.item = searchIndex[result.id] || {}; } // if there are no results then return to default and fail if (results.length === 0) { @@ -775,8 +792,7 @@ function defocusSearchBar() { return 0; }); - var length = results.length; - for (i = 0; i < length; ++i) { + for (i = 0, len = results.length; i < len; ++i) { var result = results[i]; // this validation does not make sense when searching by types @@ -833,11 +849,10 @@ function defocusSearchBar() { var vlength = val.generics.length; for (var y = 0; y < vlength; ++y) { var lev = { pos: -1, lev: MAX_LEV_DISTANCE + 1}; - var elength = elems.length; var firstGeneric = getObjectFromId(val.generics[y]).name; - for (var x = 0; x < elength; ++x) { + for (var x = 0, elength = elems.length; x < elength; ++x) { var tmp_lev = levenshtein(getObjectFromId(elems[x]).name, - firstGeneric); + firstGeneric); if (tmp_lev < lev.lev) { lev.lev = tmp_lev; lev.pos = x; @@ -861,7 +876,7 @@ function defocusSearchBar() { // Check for type name and type generics (if any). function checkType(obj, val, literalSearch) { var lev_distance = MAX_LEV_DISTANCE + 1; - var x; + var len, x, y, e_len, firstGeneric; if (obj[NAME] === val.name) { if (literalSearch === true) { if (val.generics && val.generics.length !== 0) { @@ -870,10 +885,12 @@ function defocusSearchBar() { var elems = obj[GENERICS_DATA].slice(0); var allFound = true; - for (var y = 0; allFound === true && y < val.generics.length; ++y) { + len = val.generics.length; + for (y = 0; allFound === true && y < len; ++y) { allFound = false; - var firstGeneric = getObjectFromId(val.generics[y]).name; - for (x = 0; allFound === false && x < elems.length; ++x) { + firstGeneric = getObjectFromId(val.generics[y]).name; + e_len = elems.length; + for (x = 0; allFound === false && x < e_len; ++x) { allFound = getObjectFromId(elems[x]).name === firstGeneric; } if (allFound === true) { @@ -903,12 +920,10 @@ function defocusSearchBar() { // Names didn't match so let's check if one of the generic types could. if (literalSearch === true) { if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) { - var length = obj[GENERICS_DATA].length; - for (x = 0; x < length; ++x) { - if (obj[GENERICS_DATA][x] === val.name) { - return true; - } - } + return obj[GENERICS_DATA].some( + function(name) { + return name === val.name; + }); } return false; } @@ -965,7 +980,7 @@ function defocusSearchBar() { if (typeof ret[0] === "string") { ret = [ret]; } - for (var x = 0; x < ret.length; ++x) { + for (var x = 0, len = ret.length; x < len; ++x) { var tmp = ret[x]; if (typePassesFilter(typeFilter, tmp[1]) === false) { continue; @@ -1072,23 +1087,22 @@ function defocusSearchBar() { // aliases to be before the others in the displayed results. var aliases = []; var crateAliases = []; - var i; if (filterCrates !== undefined) { if (ALIASES[filterCrates] && ALIASES[filterCrates][query.search]) { - for (i = 0; i < ALIASES[filterCrates][query.search].length; ++i) { - aliases.push( - createAliasFromItem( - searchIndex[ALIASES[filterCrates][query.search][i]])); + var query_aliases = ALIASES[filterCrates][query.search]; + var len = query_aliases.length; + for (var i = 0; i < len; ++i) { + aliases.push(createAliasFromItem(searchIndex[query_aliases[i]])); } } } else { Object.keys(ALIASES).forEach(function(crate) { if (ALIASES[crate][query.search]) { var pushTo = crate === window.currentCrate ? crateAliases : aliases; - for (i = 0; i < ALIASES[crate][query.search].length; ++i) { - pushTo.push( - createAliasFromItem( - searchIndex[ALIASES[crate][query.search][i]])); + var query_aliases = ALIASES[crate][query.search]; + var len = query_aliases.length; + for (var i = 0; i < len; ++i) { + pushTo.push(createAliasFromItem(searchIndex[query_aliases[i]])); } } }); @@ -1123,11 +1137,12 @@ function defocusSearchBar() { // quoted values mean literal search var nSearchWords = searchWords.length; - var i; + var i, it; var ty; var fullId; var returned; var in_args; + var len; if ((val.charAt(0) === "\"" || val.charAt(0) === "'") && val.charAt(val.length - 1) === val.charAt(0)) { @@ -1175,7 +1190,7 @@ function defocusSearchBar() { var input = parts[0]; // sort inputs so that order does not matter var inputs = input.split(",").map(trimmer).sort(); - for (i = 0; i < inputs.length; ++i) { + for (i = 0, len = inputs.length; i < len; ++i) { inputs[i] = extractGenerics(inputs[i]); } var output = extractGenerics(parts[1]); @@ -1200,7 +1215,7 @@ function defocusSearchBar() { is_module = true; } else { var allFound = true; - for (var it = 0; allFound === true && it < inputs.length; it++) { + for (it = 0, len = inputs.length; allFound === true && it < len; it++) { allFound = checkType(type, inputs[it], true); } in_args = allFound; @@ -1243,7 +1258,7 @@ function defocusSearchBar() { var paths = valLower.split("::"); var j; - for (j = 0; j < paths.length; ++j) { + for (j = 0, len = paths.length; j < len; ++j) { if (paths[j] === "") { paths.splice(j, 1); j -= 1; @@ -1365,7 +1380,7 @@ function defocusSearchBar() { * @return {[boolean]} [Whether the result is valid or not] */ function validateResult(name, path, keys, parent) { - for (var i = 0; i < keys.length; ++i) { + for (var i = 0, len = keys.length; i < len; ++i) { // each check is for validation so we negate the conditions and invalidate if (!( // check for an exact name match @@ -1508,15 +1523,15 @@ function defocusSearchBar() { if (type === "mod") { displayPath = path + "::"; - href = rootPath + path.replace(/::/g, "/") + "/" + + href = window.rootPath + path.replace(/::/g, "/") + "/" + name + "/index.html"; } else if (type === "primitive" || type === "keyword") { displayPath = ""; - href = rootPath + path.replace(/::/g, "/") + + href = window.rootPath + path.replace(/::/g, "/") + "/" + type + "." + name + ".html"; } else if (type === "externcrate") { displayPath = ""; - href = rootPath + name + "/index.html"; + href = window.rootPath + name + "/index.html"; } else if (item.parent !== undefined) { var myparent = item.parent; var anchor = "#" + type + "." + name; @@ -1539,13 +1554,13 @@ function defocusSearchBar() { } else { displayPath = path + "::" + myparent.name + "::"; } - href = rootPath + path.replace(/::/g, "/") + + href = window.rootPath + path.replace(/::/g, "/") + "/" + pageType + "." + pageName + ".html" + anchor; } else { displayPath = item.path + "::"; - href = rootPath + item.path.replace(/::/g, "/") + + href = window.rootPath + item.path.replace(/::/g, "/") + "/" + type + "." + name + ".html"; } return [displayPath, href]; @@ -1654,6 +1669,21 @@ function defocusSearchBar() { var ret_in_args = addTab(results.in_args, query, false); var ret_returned = addTab(results.returned, query, false); + // Navigate to the relevant tab if the current tab is empty, like in case users search + // for "-> String". If they had selected another tab previously, they have to click on + // it again. + if ((currentTab === 0 && ret_others[1] === 0) || + (currentTab === 1 && ret_in_args[1] === 0) || + (currentTab === 2 && ret_returned[1] === 0)) { + if (ret_others[1] !== 0) { + currentTab = 0; + } else if (ret_in_args[1] !== 0) { + currentTab = 1; + } else if (ret_returned[1] !== 0) { + currentTab = 2; + } + } + var output = "

Results for " + escape(query.query) + (query.type ? " (type: " + escape(query.type) + ")" : "") + "

" + "
" + @@ -1686,7 +1716,7 @@ function defocusSearchBar() { function getSmallest(arrays, positions, notDuplicates) { var start = null; - for (var it = 0; it < positions.length; ++it) { + for (var it = 0, len = positions.length; it < len; ++it) { if (arrays[it].length > positions[it] && (start === null || start > arrays[it][positions[it]].lev) && !notDuplicates[arrays[it][positions[it]].fullPath]) { @@ -1701,7 +1731,7 @@ function defocusSearchBar() { var positions = []; var notDuplicates = {}; - for (var x = 0; x < arrays.length; ++x) { + for (var x = 0, arrays_len = arrays.length; x < arrays_len; ++x) { positions.push(0); } while (ret.length < MAX_RESULTS) { @@ -1710,7 +1740,7 @@ function defocusSearchBar() { if (smallest === null) { break; } - for (x = 0; x < arrays.length && ret.length < MAX_RESULTS; ++x) { + for (x = 0; x < arrays_len && ret.length < MAX_RESULTS; ++x) { if (arrays[x].length > positions[x] && arrays[x][positions[x]].lev === smallest && !notDuplicates[arrays[x][positions[x]].fullPath]) { @@ -1730,7 +1760,7 @@ function defocusSearchBar() { "others": [], }; - for (var i = 0; i < queries.length; ++i) { + for (var i = 0, len = queries.length; i < len; ++i) { query = queries[i].trim(); if (query.length !== 0) { var tmp = execQuery(getQuery(query), searchWords, filterCrates); @@ -1787,10 +1817,12 @@ function defocusSearchBar() { // Because searching is incremental by character, only the most // recent search query is added to the browser history. if (browserSupportsHistoryApi()) { + var newURL = getNakedUrl() + "?search=" + encodeURIComponent(query.raw) + + window.location.hash; if (!history.state && !params.search) { - history.pushState(query, "", "?search=" + encodeURIComponent(query.raw)); + history.pushState(query, "", newURL); } else { - history.replaceState(query, "", "?search=" + encodeURIComponent(query.raw)); + history.replaceState(query, "", newURL); } } @@ -1884,7 +1916,7 @@ function defocusSearchBar() { ALIASES[crate][alias_name] = []; } local_aliases = aliases[alias_name]; - for (j = 0; j < local_aliases.length; ++j) { + for (j = 0, len = local_aliases.length; j < len; ++j) { ALIASES[crate][alias_name].push(local_aliases[j] + currentIndex); } } @@ -1899,7 +1931,8 @@ function defocusSearchBar() { clearInputTimeout(); if (search_input.value.length === 0) { if (browserSupportsHistoryApi()) { - history.replaceState("", window.currentCrate + " - Rust", "?search="); + history.replaceState("", window.currentCrate + " - Rust", + getNakedUrl() + window.location.hash); } hideSearchResults(); } else { @@ -1977,7 +2010,7 @@ function defocusSearchBar() { startSearch(); // Draw a convenient sidebar of known crates if we have a listing - if (rootPath === "../" || rootPath === "./") { + if (window.rootPath === "../" || window.rootPath === "./") { var sidebar = document.getElementsByClassName("sidebar-elems")[0]; if (sidebar) { var div = document.createElement("div"); @@ -1996,11 +2029,11 @@ function defocusSearchBar() { crates.sort(); for (var i = 0; i < crates.length; ++i) { var klass = "crate"; - if (rootPath !== "./" && crates[i] === window.currentCrate) { + if (window.rootPath !== "./" && crates[i] === window.currentCrate) { klass += " current"; } var link = document.createElement("a"); - link.href = rootPath + crates[i] + "/index.html"; + link.href = window.rootPath + crates[i] + "/index.html"; // The summary in the search index has HTML, so we need to // dynamically render it as plaintext. link.title = convertHTMLToPlaintext(rawSearchIndex[crates[i]].doc); @@ -2052,8 +2085,7 @@ function defocusSearchBar() { div.appendChild(h3); var ul = document.createElement("ul"); - var length = filtered.length; - for (var i = 0; i < length; ++i) { + for (var i = 0, len = filtered.length; i < len; ++i) { var item = filtered[i]; var name = item[0]; var desc = item[1]; // can be null @@ -2122,21 +2154,18 @@ function defocusSearchBar() { } var libs = Object.getOwnPropertyNames(imp); - var llength = libs.length; - for (var i = 0; i < llength; ++i) { - if (libs[i] === currentCrate) { continue; } + for (var i = 0, llength = libs.length; i < llength; ++i) { + if (libs[i] === window.currentCrate) { continue; } var structs = imp[libs[i]]; - var slength = structs.length; struct_loop: - for (var j = 0; j < slength; ++j) { + for (var j = 0, slength = structs.length; j < slength; ++j) { var struct = structs[j]; var list = struct.synthetic ? synthetic_implementors : implementors; if (struct.synthetic) { - var stlength = struct.types.length; - for (var k = 0; k < stlength; k++) { + for (var k = 0, stlength = struct.types.length; k < stlength; k++) { if (inlined_types.has(struct.types[k])) { continue struct_loop; } @@ -2151,7 +2180,7 @@ function defocusSearchBar() { var href = elem.getAttribute("href"); if (href && href.indexOf("http") !== 0) { - elem.setAttribute("href", rootPath + href); + elem.setAttribute("href", window.rootPath + href); } }); @@ -2192,7 +2221,7 @@ function defocusSearchBar() { } } - function toggleAllDocs(pageId, fromAutoCollapse) { + function toggleAllDocs(fromAutoCollapse) { var innerToggle = document.getElementById(toggleAllDocsId); if (!innerToggle) { return; @@ -2235,14 +2264,14 @@ function defocusSearchBar() { } if (!parent || !superParent || superParent.id !== "main" || hasClass(parent, "impl") === false) { - collapseDocs(e, "hide", pageId); + collapseDocs(e, "hide"); } }); } } } - function collapseDocs(toggle, mode, pageId) { + function collapseDocs(toggle, mode) { if (!toggle || !toggle.parentNode) { return; } @@ -2362,27 +2391,27 @@ function defocusSearchBar() { } } - function collapser(pageId, e, collapse) { + function collapser(e, collapse) { // inherent impl ids are like "impl" or impl-'. // they will never be hidden by default. var n = e.parentElement; if (n.id.match(/^impl(?:-\d+)?$/) === null) { // Automatically minimize all non-inherent impls if (collapse || hasClass(n, "impl")) { - collapseDocs(e, "hide", pageId); + collapseDocs(e, "hide"); } } } - function autoCollapse(pageId, collapse) { + function autoCollapse(collapse) { if (collapse) { - toggleAllDocs(pageId, true); + toggleAllDocs(true); } else if (getSettingValue("auto-hide-trait-implementations") !== "false") { var impl_list = document.getElementById("trait-implementations-list"); if (impl_list !== null) { onEachLazy(impl_list.getElementsByClassName("collapse-toggle"), function(e) { - collapser(pageId, e, collapse); + collapser(e, collapse); }); } @@ -2390,7 +2419,7 @@ function defocusSearchBar() { if (blanket_list !== null) { onEachLazy(blanket_list.getElementsByClassName("collapse-toggle"), function(e) { - collapser(pageId, e, collapse); + collapser(e, collapse); }); } } @@ -2453,7 +2482,6 @@ function defocusSearchBar() { var toggle = createSimpleToggle(false); var hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true"; var hideImplementors = getSettingValue("auto-collapse-implementors") !== "false"; - var pageId = getPageId(); var func = function(e) { var next = e.nextElementSibling; @@ -2467,7 +2495,7 @@ function defocusSearchBar() { var newToggle = toggle.cloneNode(true); insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]); if (hideMethodDocs === true && hasClass(e, "method") === true) { - collapseDocs(newToggle, "hide", pageId); + collapseDocs(newToggle, "hide"); } } }; @@ -2491,7 +2519,7 @@ function defocusSearchBar() { // In case the option "auto-collapse implementors" is not set to false, we collapse // all implementors. if (hideImplementors === true && e.parentNode.id === "implementors-list") { - collapseDocs(newToggle, "hide", pageId); + collapseDocs(newToggle, "hide"); } } }; @@ -2505,7 +2533,7 @@ function defocusSearchBar() { if (e.id.match(/^impl(?:-\d+)?$/) === null) { // Automatically minimize all non-inherent impls if (hasClass(e, "impl") === true) { - collapseDocs(newToggle, "hide", pageId); + collapseDocs(newToggle, "hide"); } } }; @@ -2540,14 +2568,12 @@ function defocusSearchBar() { } onEachLazy(document.getElementsByClassName("impl-items"), function(e) { onEachLazy(e.getElementsByClassName("associatedconstant"), func); - var hiddenElems = e.getElementsByClassName("hidden"); - var needToggle = false; - - var needToggle = onEachLazy(e.getElementsByClassName("hidden"), function(hiddenElem) { - if (hasClass(hiddenElem, "content") === false && - hasClass(hiddenElem, "docblock") === false) { - return true; - } + // We transform the DOM iterator into a vec of DOM elements to prevent performance + // issues on webkit browsers. + var hiddenElems = Array.prototype.slice.call(e.getElementsByClassName("hidden")); + var needToggle = hiddenElems.some(function(hiddenElem) { + return hasClass(hiddenElem, "content") === false && + hasClass(hiddenElem, "docblock") === false; }); if (needToggle === true) { var inner_toggle = newToggle.cloneNode(true); @@ -2650,10 +2676,10 @@ function defocusSearchBar() { onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper); onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper); - var pageId = getPageId(); - autoCollapse(pageId, getSettingValue("collapse") === "true"); + autoCollapse(getSettingValue("collapse") === "true"); + var pageId = getPageId(); if (pageId !== null) { expandSection(pageId); } @@ -2763,9 +2789,9 @@ function defocusSearchBar() { if (search_input.value !== "" && hasClass(search, "hidden")) { showSearchResults(search); if (browserSupportsHistoryApi()) { - history.replaceState(search_input.value, - "", - "?search=" + encodeURIComponent(search_input.value)); + var extra = "?search=" + encodeURIComponent(search_input.value); + history.replaceState(search_input.value, "", + getNakedUrl() + extra + window.location.hash); } document.title = searchTitle; } @@ -2853,7 +2879,7 @@ function defocusSearchBar() { return 0; }); var savedCrate = getSettingValue("saved-filter-crate"); - for (var i = 0; i < crates_text.length; ++i) { + for (var i = 0, len = crates_text.length; i < len; ++i) { var option = document.createElement("option"); option.value = crates_text[i]; option.innerText = crates_text[i];