2018-12-04 21:59:27 +00:00
|
|
|
|
// Local js definitions:
|
2021-05-14 11:56:15 +00:00
|
|
|
|
/* global addClass, getSettingValue, hasClass, searchState */
|
|
|
|
|
/* global onEach, onEachLazy, removeClass */
|
2021-03-05 15:09:46 +00:00
|
|
|
|
/* global switchTheme, useSystemTheme */
|
2013-09-19 05:18:38 +00:00
|
|
|
|
|
2018-11-06 00:40:12 +00:00
|
|
|
|
if (!String.prototype.startsWith) {
|
|
|
|
|
String.prototype.startsWith = function(searchString, position) {
|
|
|
|
|
position = position || 0;
|
|
|
|
|
return this.indexOf(searchString, position) === position;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (!String.prototype.endsWith) {
|
|
|
|
|
String.prototype.endsWith = function(suffix, length) {
|
|
|
|
|
var l = length || this.length;
|
|
|
|
|
return this.indexOf(suffix, l - suffix.length) !== -1;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-16 15:31:07 +00:00
|
|
|
|
if (!DOMTokenList.prototype.add) {
|
|
|
|
|
DOMTokenList.prototype.add = function(className) {
|
|
|
|
|
if (className && !hasClass(this, className)) {
|
|
|
|
|
if (this.className && this.className.length > 0) {
|
|
|
|
|
this.className += " " + className;
|
|
|
|
|
} else {
|
|
|
|
|
this.className = className;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!DOMTokenList.prototype.remove) {
|
|
|
|
|
DOMTokenList.prototype.remove = function(className) {
|
|
|
|
|
if (className && this.className) {
|
|
|
|
|
this.className = (" " + this.className + " ").replace(" " + className + " ", " ")
|
|
|
|
|
.trim();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-24 03:22:29 +00:00
|
|
|
|
// Get a value from the rustdoc-vars div, which is used to convey data from
|
|
|
|
|
// Rust to the JS. If there is no such element, return null.
|
|
|
|
|
function getVar(name) {
|
|
|
|
|
var el = document.getElementById("rustdoc-vars");
|
|
|
|
|
if (el) {
|
|
|
|
|
return el.attributes["data-" + name].value;
|
|
|
|
|
} else {
|
|
|
|
|
return null;
|
2021-01-18 11:03:53 +00:00
|
|
|
|
}
|
2021-11-24 03:22:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Given a basename (e.g. "storage") and an extension (e.g. ".js"), return a URL
|
|
|
|
|
// for a resource under the root-path, with the resource-suffix.
|
|
|
|
|
function resourcePath(basename, extension) {
|
|
|
|
|
return getVar("root-path") + basename + getVar("resource-suffix") + extension;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function () {
|
|
|
|
|
window.rootPath = getVar("root-path");
|
|
|
|
|
window.currentCrate = getVar("current-crate");
|
2021-11-24 05:23:54 +00:00
|
|
|
|
window.searchJS = resourcePath("search", ".js");
|
|
|
|
|
window.searchIndexJS = resourcePath("search-index", ".js");
|
2021-01-18 11:03:53 +00:00
|
|
|
|
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,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}());
|
2020-11-08 13:49:29 +00:00
|
|
|
|
|
|
|
|
|
// Gets the human-readable string for the virtual-key code of the
|
|
|
|
|
// given KeyboardEvent, ev.
|
|
|
|
|
//
|
|
|
|
|
// This function is meant as a polyfill for KeyboardEvent#key,
|
2020-11-08 16:12:03 +00:00
|
|
|
|
// since it is not supported in IE 11 or Chrome for Android. We also test for
|
2020-11-08 13:49:29 +00:00
|
|
|
|
// KeyboardEvent#keyCode because the handleShortcut handler is
|
|
|
|
|
// also registered for the keydown event, because Blink doesn't fire
|
|
|
|
|
// keypress on hitting the Escape key.
|
|
|
|
|
//
|
|
|
|
|
// So I guess you could say things are getting pretty interoperable.
|
|
|
|
|
function getVirtualKey(ev) {
|
|
|
|
|
if ("key" in ev && typeof ev.key != "undefined") {
|
|
|
|
|
return ev.key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var c = ev.charCode || ev.keyCode;
|
|
|
|
|
if (c == 27) {
|
|
|
|
|
return "Escape";
|
|
|
|
|
}
|
|
|
|
|
return String.fromCharCode(c);
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-05 15:19:58 +00:00
|
|
|
|
var THEME_PICKER_ELEMENT_ID = "theme-picker";
|
|
|
|
|
var THEMES_ELEMENT_ID = "theme-choices";
|
2021-11-29 16:14:05 +00:00
|
|
|
|
var MAIN_ID = "main-content";
|
2021-03-05 15:16:03 +00:00
|
|
|
|
|
2020-10-30 21:27:00 +00:00
|
|
|
|
function getThemesElement() {
|
2021-03-05 15:19:58 +00:00
|
|
|
|
return document.getElementById(THEMES_ELEMENT_ID);
|
2020-10-30 21:27:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getThemePickerElement() {
|
2021-03-05 15:19:58 +00:00
|
|
|
|
return document.getElementById(THEME_PICKER_ELEMENT_ID);
|
2020-10-30 21:27:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-01-25 12:21:12 +00:00
|
|
|
|
// Returns the current URL without any query parameter or hash.
|
|
|
|
|
function getNakedUrl() {
|
|
|
|
|
return window.location.href.split("?")[0].split("#")[0];
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-05 15:09:46 +00:00
|
|
|
|
function showThemeButtonState() {
|
|
|
|
|
var themePicker = getThemePickerElement();
|
|
|
|
|
var themeChoices = getThemesElement();
|
|
|
|
|
|
|
|
|
|
themeChoices.style.display = "block";
|
|
|
|
|
themePicker.style.borderBottomRightRadius = "0";
|
|
|
|
|
themePicker.style.borderBottomLeftRadius = "0";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function hideThemeButtonState() {
|
|
|
|
|
var themePicker = getThemePickerElement();
|
|
|
|
|
var themeChoices = getThemesElement();
|
|
|
|
|
|
|
|
|
|
themeChoices.style.display = "none";
|
|
|
|
|
themePicker.style.borderBottomRightRadius = "3px";
|
|
|
|
|
themePicker.style.borderBottomLeftRadius = "3px";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set up the theme picker list.
|
|
|
|
|
(function () {
|
|
|
|
|
var themeChoices = getThemesElement();
|
|
|
|
|
var themePicker = getThemePickerElement();
|
2021-11-24 03:22:29 +00:00
|
|
|
|
var availableThemes = getVar("themes").split(",");
|
2021-03-05 15:09:46 +00:00
|
|
|
|
|
|
|
|
|
function switchThemeButtonState() {
|
|
|
|
|
if (themeChoices.style.display === "block") {
|
|
|
|
|
hideThemeButtonState();
|
|
|
|
|
} else {
|
|
|
|
|
showThemeButtonState();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleThemeButtonsBlur(e) {
|
|
|
|
|
var active = document.activeElement;
|
|
|
|
|
var related = e.relatedTarget;
|
|
|
|
|
|
2021-03-05 15:19:58 +00:00
|
|
|
|
if (active.id !== THEME_PICKER_ELEMENT_ID &&
|
|
|
|
|
(!active.parentNode || active.parentNode.id !== THEMES_ELEMENT_ID) &&
|
2021-03-05 15:09:46 +00:00
|
|
|
|
(!related ||
|
2021-03-05 15:19:58 +00:00
|
|
|
|
(related.id !== THEME_PICKER_ELEMENT_ID &&
|
|
|
|
|
(!related.parentNode || related.parentNode.id !== THEMES_ELEMENT_ID)))) {
|
2021-03-05 15:09:46 +00:00
|
|
|
|
hideThemeButtonState();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
themePicker.onclick = switchThemeButtonState;
|
|
|
|
|
themePicker.onblur = handleThemeButtonsBlur;
|
|
|
|
|
availableThemes.forEach(function(item) {
|
|
|
|
|
var but = document.createElement("button");
|
|
|
|
|
but.textContent = item;
|
|
|
|
|
but.onclick = function() {
|
|
|
|
|
switchTheme(window.currentTheme, window.mainTheme, item, true);
|
|
|
|
|
useSystemTheme(false);
|
|
|
|
|
};
|
|
|
|
|
but.onblur = handleThemeButtonsBlur;
|
|
|
|
|
themeChoices.appendChild(but);
|
|
|
|
|
});
|
|
|
|
|
}());
|
|
|
|
|
|
2014-01-10 04:59:53 +00:00
|
|
|
|
(function() {
|
2013-09-19 05:18:38 +00:00
|
|
|
|
"use strict";
|
|
|
|
|
|
2021-04-13 06:50:18 +00:00
|
|
|
|
window.searchState = {
|
2021-05-11 09:47:39 +00:00
|
|
|
|
loadingText: "Loading search results...",
|
|
|
|
|
input: document.getElementsByClassName("search-input")[0],
|
|
|
|
|
outputElement: function() {
|
|
|
|
|
return document.getElementById("search");
|
|
|
|
|
},
|
2021-05-20 14:01:08 +00:00
|
|
|
|
title: document.title,
|
2021-05-11 09:47:39 +00:00
|
|
|
|
titleBeforeSearch: document.title,
|
|
|
|
|
timeout: null,
|
|
|
|
|
// On the search screen, so you remain on the last tab you opened.
|
|
|
|
|
//
|
|
|
|
|
// 0 for "In Names"
|
|
|
|
|
// 1 for "In Parameters"
|
|
|
|
|
// 2 for "In Return Types"
|
|
|
|
|
currentTab: 0,
|
2021-05-09 19:56:21 +00:00
|
|
|
|
// tab and back preserves the element that was focused.
|
|
|
|
|
focusedByTab: [null, null, null],
|
2021-05-11 09:47:39 +00:00
|
|
|
|
clearInputTimeout: function() {
|
|
|
|
|
if (searchState.timeout !== null) {
|
|
|
|
|
clearTimeout(searchState.timeout);
|
|
|
|
|
searchState.timeout = null;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// Sets the focus on the search bar at the top of the page
|
|
|
|
|
focus: function() {
|
|
|
|
|
searchState.input.focus();
|
|
|
|
|
},
|
|
|
|
|
// Removes the focus from the search bar.
|
|
|
|
|
defocus: function() {
|
|
|
|
|
searchState.input.blur();
|
|
|
|
|
},
|
|
|
|
|
showResults: function(search) {
|
|
|
|
|
if (search === null || typeof search === 'undefined') {
|
|
|
|
|
search = searchState.outputElement();
|
2021-04-13 06:50:18 +00:00
|
|
|
|
}
|
2021-05-11 09:47:39 +00:00
|
|
|
|
addClass(main, "hidden");
|
|
|
|
|
removeClass(search, "hidden");
|
|
|
|
|
searchState.mouseMovedAfterSearch = false;
|
2021-04-13 06:50:18 +00:00
|
|
|
|
document.title = searchState.title;
|
2021-05-11 09:47:39 +00:00
|
|
|
|
},
|
|
|
|
|
hideResults: function(search) {
|
|
|
|
|
if (search === null || typeof search === 'undefined') {
|
|
|
|
|
search = searchState.outputElement();
|
|
|
|
|
}
|
|
|
|
|
addClass(search, "hidden");
|
|
|
|
|
removeClass(main, "hidden");
|
|
|
|
|
document.title = searchState.titleBeforeSearch;
|
|
|
|
|
// We also remove the query parameter from the URL.
|
|
|
|
|
if (searchState.browserSupportsHistoryApi()) {
|
|
|
|
|
history.replaceState("", window.currentCrate + " - Rust",
|
|
|
|
|
getNakedUrl() + window.location.hash);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
getQueryStringParams: function() {
|
|
|
|
|
var params = {};
|
|
|
|
|
window.location.search.substring(1).split("&").
|
|
|
|
|
map(function(s) {
|
|
|
|
|
var pair = s.split("=");
|
|
|
|
|
params[decodeURIComponent(pair[0])] =
|
|
|
|
|
typeof pair[1] === "undefined" ? null : decodeURIComponent(pair[1]);
|
|
|
|
|
});
|
|
|
|
|
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() {
|
|
|
|
|
return window.history && typeof window.history.pushState === "function";
|
|
|
|
|
},
|
|
|
|
|
setup: function() {
|
|
|
|
|
var search_input = searchState.input;
|
|
|
|
|
if (!searchState.input) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
function loadScript(url) {
|
|
|
|
|
var script = document.createElement('script');
|
|
|
|
|
script.src = url;
|
|
|
|
|
document.head.append(script);
|
2021-04-13 06:50:18 +00:00
|
|
|
|
}
|
2018-04-24 18:23:57 +00:00
|
|
|
|
|
2021-05-11 09:47:39 +00:00
|
|
|
|
var searchLoaded = false;
|
|
|
|
|
function loadSearch() {
|
|
|
|
|
if (!searchLoaded) {
|
|
|
|
|
searchLoaded = true;
|
|
|
|
|
loadScript(window.searchJS);
|
|
|
|
|
loadScript(window.searchIndexJS);
|
|
|
|
|
}
|
2021-04-13 06:50:18 +00:00
|
|
|
|
}
|
2017-10-14 14:31:48 +00:00
|
|
|
|
|
2021-05-11 09:47:39 +00:00
|
|
|
|
search_input.addEventListener("focus", function() {
|
|
|
|
|
searchState.putBackSearch(this);
|
|
|
|
|
search_input.origPlaceholder = searchState.input.placeholder;
|
|
|
|
|
search_input.placeholder = "Type your search here.";
|
|
|
|
|
loadSearch();
|
|
|
|
|
});
|
|
|
|
|
search_input.addEventListener("blur", function() {
|
|
|
|
|
search_input.placeholder = searchState.input.origPlaceholder;
|
|
|
|
|
});
|
2020-06-02 02:18:38 +00:00
|
|
|
|
|
2021-10-27 01:50:07 +00:00
|
|
|
|
if (search_input.value != '') {
|
|
|
|
|
loadSearch();
|
|
|
|
|
}
|
2018-08-15 18:08:25 +00:00
|
|
|
|
|
2021-05-11 09:47:39 +00:00
|
|
|
|
// `crates{version}.js` should always be loaded before this script, so we can use it
|
|
|
|
|
// safely.
|
|
|
|
|
searchState.addCrateDropdown(window.ALL_CRATES);
|
|
|
|
|
var params = searchState.getQueryStringParams();
|
|
|
|
|
if (params.search !== undefined) {
|
|
|
|
|
var search = searchState.outputElement();
|
|
|
|
|
search.innerHTML = "<h3 style=\"text-align: center;\">" +
|
|
|
|
|
searchState.loadingText + "</h3>";
|
|
|
|
|
searchState.showResults(search);
|
|
|
|
|
loadSearch();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
addCrateDropdown: function(crates) {
|
|
|
|
|
var elem = document.getElementById("crate-search");
|
2021-04-01 17:56:11 +00:00
|
|
|
|
|
2021-05-11 09:47:39 +00:00
|
|
|
|
if (!elem) {
|
|
|
|
|
return;
|
2021-04-13 07:35:36 +00:00
|
|
|
|
}
|
2021-05-11 09:47:39 +00:00
|
|
|
|
var savedCrate = getSettingValue("saved-filter-crate");
|
|
|
|
|
for (var i = 0, len = crates.length; i < len; ++i) {
|
|
|
|
|
var option = document.createElement("option");
|
|
|
|
|
option.value = crates[i];
|
|
|
|
|
option.innerText = crates[i];
|
|
|
|
|
elem.appendChild(option);
|
|
|
|
|
// Set the crate filter from saved storage, if the current page has the saved crate
|
|
|
|
|
// filter.
|
|
|
|
|
//
|
|
|
|
|
// If not, ignore the crate filter -- we want to support filtering for crates on
|
|
|
|
|
// sites like doc.rust-lang.org where the crates may differ from page to page while
|
|
|
|
|
// on the
|
|
|
|
|
// same domain.
|
|
|
|
|
if (crates[i] === savedCrate) {
|
|
|
|
|
elem.value = savedCrate;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
2021-04-13 07:35:36 +00:00
|
|
|
|
};
|
2020-05-31 12:27:33 +00:00
|
|
|
|
|
2018-04-04 14:16:53 +00:00
|
|
|
|
function getPageId() {
|
2020-03-30 11:59:10 +00:00
|
|
|
|
if (window.location.hash) {
|
|
|
|
|
var tmp = window.location.hash.replace(/^#/, "");
|
|
|
|
|
if (tmp.length > 0) {
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
2018-04-04 14:16:53 +00:00
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-05 23:42:33 +00:00
|
|
|
|
function showSidebar() {
|
2017-12-07 21:55:14 +00:00
|
|
|
|
var elems = document.getElementsByClassName("sidebar-elems")[0];
|
|
|
|
|
if (elems) {
|
2017-12-19 23:44:44 +00:00
|
|
|
|
addClass(elems, "show-it");
|
2017-12-07 21:55:14 +00:00
|
|
|
|
}
|
2018-11-16 15:31:07 +00:00
|
|
|
|
var sidebar = document.getElementsByClassName("sidebar")[0];
|
2017-12-19 23:44:44 +00:00
|
|
|
|
if (sidebar) {
|
2018-11-16 15:31:07 +00:00
|
|
|
|
addClass(sidebar, "mobile");
|
2017-12-19 23:44:44 +00:00
|
|
|
|
var filler = document.getElementById("sidebar-filler");
|
|
|
|
|
if (!filler) {
|
|
|
|
|
var div = document.createElement("div");
|
|
|
|
|
div.id = "sidebar-filler";
|
|
|
|
|
sidebar.appendChild(div);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-12-05 23:42:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function hideSidebar() {
|
2017-12-07 21:55:14 +00:00
|
|
|
|
var elems = document.getElementsByClassName("sidebar-elems")[0];
|
|
|
|
|
if (elems) {
|
2017-12-19 23:44:44 +00:00
|
|
|
|
removeClass(elems, "show-it");
|
2017-12-07 21:55:14 +00:00
|
|
|
|
}
|
2018-11-16 15:31:07 +00:00
|
|
|
|
var sidebar = document.getElementsByClassName("sidebar")[0];
|
|
|
|
|
removeClass(sidebar, "mobile");
|
2017-12-19 23:44:44 +00:00
|
|
|
|
var filler = document.getElementById("sidebar-filler");
|
|
|
|
|
if (filler) {
|
|
|
|
|
filler.remove();
|
|
|
|
|
}
|
2018-11-16 15:31:07 +00:00
|
|
|
|
document.getElementsByTagName("body")[0].style.marginTop = "";
|
2017-12-05 23:42:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-04-13 06:50:18 +00:00
|
|
|
|
var toggleAllDocsId = "toggle-all-docs";
|
2021-11-29 16:14:05 +00:00
|
|
|
|
var main = document.getElementById(MAIN_ID);
|
2019-11-05 16:41:40 +00:00
|
|
|
|
var savedHash = "";
|
2018-11-26 16:17:38 +00:00
|
|
|
|
|
2019-11-05 16:41:40 +00:00
|
|
|
|
function handleHashes(ev) {
|
2020-05-17 13:34:59 +00:00
|
|
|
|
var elem;
|
2021-04-13 06:50:18 +00:00
|
|
|
|
var search = searchState.outputElement();
|
2019-11-04 12:14:36 +00:00
|
|
|
|
if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
|
2019-11-05 16:41:40 +00:00
|
|
|
|
// This block occurs when clicking on an element in the navbar while
|
|
|
|
|
// in a search.
|
2021-04-13 06:50:18 +00:00
|
|
|
|
searchState.hideResults(search);
|
2018-11-16 15:31:07 +00:00
|
|
|
|
var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
|
2021-04-13 06:50:18 +00:00
|
|
|
|
if (searchState.browserSupportsHistoryApi()) {
|
2021-01-25 12:21:12 +00:00
|
|
|
|
// `window.location.search`` contains all the query parameters, not just `search`.
|
|
|
|
|
history.replaceState(hash, "",
|
|
|
|
|
getNakedUrl() + window.location.search + "#" + hash);
|
2017-11-10 18:40:46 +00:00
|
|
|
|
}
|
2020-05-17 13:34:59 +00:00
|
|
|
|
elem = document.getElementById(hash);
|
2017-11-06 20:14:37 +00:00
|
|
|
|
if (elem) {
|
|
|
|
|
elem.scrollIntoView();
|
|
|
|
|
}
|
2013-10-02 17:32:13 +00:00
|
|
|
|
}
|
2019-11-05 16:41:40 +00:00
|
|
|
|
// This part is used in case an element is not visible.
|
|
|
|
|
if (savedHash !== window.location.hash) {
|
|
|
|
|
savedHash = window.location.hash;
|
|
|
|
|
if (savedHash.length === 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-05-08 12:21:57 +00:00
|
|
|
|
expandSection(savedHash.slice(1)); // we remove the '#'
|
2019-11-05 16:41:40 +00:00
|
|
|
|
}
|
2013-10-02 17:32:13 +00:00
|
|
|
|
}
|
2018-08-23 07:43:06 +00:00
|
|
|
|
|
2019-11-05 16:41:40 +00:00
|
|
|
|
function onHashChange(ev) {
|
|
|
|
|
// If we're in mobile mode, we should hide the sidebar in any case.
|
|
|
|
|
hideSidebar();
|
2019-11-07 09:16:14 +00:00
|
|
|
|
handleHashes(ev);
|
2019-11-05 16:41:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-04-18 21:01:47 +00:00
|
|
|
|
function openParentDetails(elem) {
|
|
|
|
|
while (elem) {
|
|
|
|
|
if (elem.tagName === "DETAILS") {
|
|
|
|
|
elem.open = true;
|
|
|
|
|
}
|
|
|
|
|
elem = elem.parentNode;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-25 10:34:04 +00:00
|
|
|
|
function expandSection(id) {
|
2021-05-08 12:21:57 +00:00
|
|
|
|
openParentDetails(document.getElementById(id));
|
2018-08-23 07:43:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-12-12 22:32:44 +00:00
|
|
|
|
function getHelpElement(build) {
|
2021-05-09 20:49:22 +00:00
|
|
|
|
if (build) {
|
2020-12-12 22:32:44 +00:00
|
|
|
|
buildHelperPopup();
|
|
|
|
|
}
|
2019-09-09 15:04:28 +00:00
|
|
|
|
return document.getElementById("help");
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-08 11:38:47 +00:00
|
|
|
|
function displayHelp(display, ev, help) {
|
2021-05-09 20:49:22 +00:00
|
|
|
|
if (display) {
|
2020-12-12 22:32:44 +00:00
|
|
|
|
help = help ? help : getHelpElement(true);
|
2017-10-14 16:43:00 +00:00
|
|
|
|
if (hasClass(help, "hidden")) {
|
|
|
|
|
ev.preventDefault();
|
|
|
|
|
removeClass(help, "hidden");
|
|
|
|
|
addClass(document.body, "blur");
|
|
|
|
|
}
|
2020-12-12 22:32:44 +00:00
|
|
|
|
} else {
|
|
|
|
|
// No need to build the help popup if we want to hide it in case it hasn't been
|
|
|
|
|
// built yet...
|
|
|
|
|
help = help ? help : getHelpElement(false);
|
2021-05-09 20:49:22 +00:00
|
|
|
|
if (help && !hasClass(help, "hidden")) {
|
2020-12-12 22:32:44 +00:00
|
|
|
|
ev.preventDefault();
|
|
|
|
|
addClass(help, "hidden");
|
|
|
|
|
removeClass(document.body, "blur");
|
|
|
|
|
}
|
2017-10-14 16:43:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-09 15:04:28 +00:00
|
|
|
|
function handleEscape(ev) {
|
2020-12-12 22:32:44 +00:00
|
|
|
|
var help = getHelpElement(false);
|
2021-04-13 06:50:18 +00:00
|
|
|
|
var search = searchState.outputElement();
|
2021-05-18 12:32:20 +00:00
|
|
|
|
if (help && !hasClass(help, "hidden")) {
|
2019-02-08 11:38:47 +00:00
|
|
|
|
displayHelp(false, ev, help);
|
2021-05-18 12:32:20 +00:00
|
|
|
|
} else if (search && !hasClass(search, "hidden")) {
|
2021-04-13 06:50:18 +00:00
|
|
|
|
searchState.clearInputTimeout();
|
2018-03-18 15:32:41 +00:00
|
|
|
|
ev.preventDefault();
|
2021-04-13 06:50:18 +00:00
|
|
|
|
searchState.hideResults(search);
|
2018-03-05 22:37:33 +00:00
|
|
|
|
}
|
2021-04-13 07:35:36 +00:00
|
|
|
|
searchState.defocus();
|
2020-10-30 20:03:01 +00:00
|
|
|
|
hideThemeButtonState();
|
2018-03-18 15:32:41 +00:00
|
|
|
|
}
|
2013-09-19 05:18:38 +00:00
|
|
|
|
|
2021-04-13 06:50:18 +00:00
|
|
|
|
var disableShortcuts = getSettingValue("disable-shortcuts") === "true";
|
2018-03-18 15:32:41 +00:00
|
|
|
|
function handleShortcut(ev) {
|
2015-11-05 10:39:02 +00:00
|
|
|
|
// Don't interfere with browser shortcuts
|
2021-05-09 20:49:22 +00:00
|
|
|
|
if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts) {
|
2015-11-05 10:39:02 +00:00
|
|
|
|
return;
|
2018-03-05 22:37:33 +00:00
|
|
|
|
}
|
2015-11-05 10:39:02 +00:00
|
|
|
|
|
2018-03-18 15:32:41 +00:00
|
|
|
|
if (document.activeElement.tagName === "INPUT") {
|
|
|
|
|
switch (getVirtualKey(ev)) {
|
|
|
|
|
case "Escape":
|
2019-09-09 15:04:28 +00:00
|
|
|
|
handleEscape(ev);
|
2018-03-18 15:32:41 +00:00
|
|
|
|
break;
|
2015-04-11 22:32:53 +00:00
|
|
|
|
}
|
2018-03-18 15:32:41 +00:00
|
|
|
|
} else {
|
|
|
|
|
switch (getVirtualKey(ev)) {
|
|
|
|
|
case "Escape":
|
2019-09-09 15:04:28 +00:00
|
|
|
|
handleEscape(ev);
|
2018-03-18 15:32:41 +00:00
|
|
|
|
break;
|
2015-07-07 14:15:22 +00:00
|
|
|
|
|
2018-03-18 15:32:41 +00:00
|
|
|
|
case "s":
|
|
|
|
|
case "S":
|
2019-09-09 15:04:28 +00:00
|
|
|
|
displayHelp(false, ev);
|
2018-03-18 15:32:41 +00:00
|
|
|
|
ev.preventDefault();
|
2021-04-13 07:35:36 +00:00
|
|
|
|
searchState.focus();
|
2018-03-18 15:32:41 +00:00
|
|
|
|
break;
|
2015-07-07 14:15:22 +00:00
|
|
|
|
|
2018-03-18 15:32:41 +00:00
|
|
|
|
case "+":
|
|
|
|
|
case "-":
|
|
|
|
|
ev.preventDefault();
|
|
|
|
|
toggleAllDocs();
|
|
|
|
|
break;
|
2016-05-21 02:21:35 +00:00
|
|
|
|
|
2018-03-18 15:32:41 +00:00
|
|
|
|
case "?":
|
2020-08-11 09:30:50 +00:00
|
|
|
|
displayHelp(true, ev);
|
2018-03-18 15:32:41 +00:00
|
|
|
|
break;
|
2020-10-30 21:27:00 +00:00
|
|
|
|
|
2020-11-05 13:24:45 +00:00
|
|
|
|
case "t":
|
|
|
|
|
case "T":
|
|
|
|
|
displayHelp(false, ev);
|
|
|
|
|
ev.preventDefault();
|
|
|
|
|
var themePicker = getThemePickerElement();
|
|
|
|
|
themePicker.click();
|
|
|
|
|
themePicker.focus();
|
|
|
|
|
break;
|
|
|
|
|
|
2020-10-30 21:27:00 +00:00
|
|
|
|
default:
|
2021-03-05 15:16:03 +00:00
|
|
|
|
if (getThemePickerElement().parentNode.contains(ev.target)) {
|
2020-10-30 21:27:00 +00:00
|
|
|
|
handleThemeKeyDown(ev);
|
|
|
|
|
}
|
2013-09-27 18:06:07 +00:00
|
|
|
|
}
|
2013-09-19 05:18:38 +00:00
|
|
|
|
}
|
2015-07-07 14:15:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-10-30 21:27:00 +00:00
|
|
|
|
function handleThemeKeyDown(ev) {
|
|
|
|
|
var active = document.activeElement;
|
|
|
|
|
var themes = getThemesElement();
|
|
|
|
|
switch (getVirtualKey(ev)) {
|
|
|
|
|
case "ArrowUp":
|
|
|
|
|
ev.preventDefault();
|
2021-03-05 15:19:58 +00:00
|
|
|
|
if (active.previousElementSibling && ev.target.id !== THEME_PICKER_ELEMENT_ID) {
|
2020-10-30 21:27:00 +00:00
|
|
|
|
active.previousElementSibling.focus();
|
|
|
|
|
} else {
|
|
|
|
|
showThemeButtonState();
|
|
|
|
|
themes.lastElementChild.focus();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "ArrowDown":
|
|
|
|
|
ev.preventDefault();
|
2021-03-05 15:19:58 +00:00
|
|
|
|
if (active.nextElementSibling && ev.target.id !== THEME_PICKER_ELEMENT_ID) {
|
2020-10-30 21:27:00 +00:00
|
|
|
|
active.nextElementSibling.focus();
|
|
|
|
|
} else {
|
|
|
|
|
showThemeButtonState();
|
|
|
|
|
themes.firstElementChild.focus();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "Enter":
|
|
|
|
|
case "Return":
|
|
|
|
|
case "Space":
|
2021-03-05 15:19:58 +00:00
|
|
|
|
if (ev.target.id === THEME_PICKER_ELEMENT_ID && themes.style.display === "none") {
|
2020-10-30 21:27:00 +00:00
|
|
|
|
ev.preventDefault();
|
|
|
|
|
showThemeButtonState();
|
|
|
|
|
themes.firstElementChild.focus();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "Home":
|
|
|
|
|
ev.preventDefault();
|
|
|
|
|
themes.firstElementChild.focus();
|
|
|
|
|
break;
|
|
|
|
|
case "End":
|
|
|
|
|
ev.preventDefault();
|
|
|
|
|
themes.lastElementChild.focus();
|
|
|
|
|
break;
|
|
|
|
|
// The escape key is handled in handleEscape, not here,
|
|
|
|
|
// so that pressing escape will close the menu even if it isn't focused
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-22 13:14:37 +00:00
|
|
|
|
document.addEventListener("keypress", handleShortcut);
|
|
|
|
|
document.addEventListener("keydown", handleShortcut);
|
2013-09-19 05:18:38 +00:00
|
|
|
|
|
2020-05-17 12:49:04 +00:00
|
|
|
|
(function() {
|
|
|
|
|
var x = document.getElementsByClassName("version-selector");
|
|
|
|
|
if (x.length > 0) {
|
|
|
|
|
x[0].onchange = function() {
|
|
|
|
|
var i, match,
|
|
|
|
|
url = document.location.href,
|
|
|
|
|
stripped = "",
|
2021-01-18 11:03:53 +00:00
|
|
|
|
len = window.rootPath.match(/\.\.\//g).length + 1;
|
2013-09-19 05:18:38 +00:00
|
|
|
|
|
2020-05-17 12:49:04 +00:00
|
|
|
|
for (i = 0; i < len; ++i) {
|
2021-05-14 11:56:15 +00:00
|
|
|
|
match = url.match(/\/[^/]*$/);
|
2020-05-17 12:49:04 +00:00
|
|
|
|
if (i < len - 1) {
|
|
|
|
|
stripped = match[0] + stripped;
|
|
|
|
|
}
|
|
|
|
|
url = url.substring(0, url.length - match[0].length);
|
2017-04-14 14:37:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-26 09:48:59 +00:00
|
|
|
|
var selectedVersion = document.getElementsByClassName("version-selector")[0].value;
|
|
|
|
|
url += "/" + selectedVersion + stripped;
|
2017-04-14 14:37:09 +00:00
|
|
|
|
|
2020-05-17 12:49:04 +00:00
|
|
|
|
document.location.href = url;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}());
|
2015-07-07 14:15:22 +00:00
|
|
|
|
|
2015-03-05 07:35:43 +00:00
|
|
|
|
// delayed sidebar rendering.
|
2020-05-17 12:57:19 +00:00
|
|
|
|
window.initSidebarItems = function(items) {
|
2018-11-16 15:31:07 +00:00
|
|
|
|
var sidebar = document.getElementsByClassName("sidebar-elems")[0];
|
2021-11-04 15:27:02 +00:00
|
|
|
|
var others;
|
2015-03-05 07:35:43 +00:00
|
|
|
|
var current = window.sidebarCurrent;
|
2021-05-02 14:35:48 +00:00
|
|
|
|
|
|
|
|
|
function addSidebarCrates(crates) {
|
2021-05-31 09:51:22 +00:00
|
|
|
|
if (!hasClass(document.body, "crate")) {
|
|
|
|
|
// We only want to list crates on the crate page.
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-05-02 14:35:48 +00:00
|
|
|
|
// Draw a convenient sidebar of known crates if we have a listing
|
|
|
|
|
var div = document.createElement("div");
|
|
|
|
|
div.className = "block crate";
|
|
|
|
|
div.innerHTML = "<h3>Crates</h3>";
|
|
|
|
|
var ul = document.createElement("ul");
|
|
|
|
|
div.appendChild(ul);
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < crates.length; ++i) {
|
|
|
|
|
var klass = "crate";
|
|
|
|
|
if (window.rootPath !== "./" && crates[i] === window.currentCrate) {
|
|
|
|
|
klass += " current";
|
|
|
|
|
}
|
|
|
|
|
var link = document.createElement("a");
|
|
|
|
|
link.href = window.rootPath + crates[i] + "/index.html";
|
|
|
|
|
link.className = klass;
|
|
|
|
|
link.textContent = crates[i];
|
|
|
|
|
|
|
|
|
|
var li = document.createElement("li");
|
|
|
|
|
li.appendChild(link);
|
|
|
|
|
ul.appendChild(li);
|
|
|
|
|
}
|
2021-11-04 15:27:02 +00:00
|
|
|
|
others.appendChild(div);
|
2021-05-02 14:35:48 +00:00
|
|
|
|
}
|
2015-03-05 07:35:43 +00:00
|
|
|
|
|
|
|
|
|
function block(shortty, longty) {
|
|
|
|
|
var filtered = items[shortty];
|
2018-11-16 15:31:07 +00:00
|
|
|
|
if (!filtered) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2015-03-05 07:35:43 +00:00
|
|
|
|
|
2018-11-16 15:31:07 +00:00
|
|
|
|
var div = document.createElement("div");
|
|
|
|
|
div.className = "block " + shortty;
|
|
|
|
|
var h3 = document.createElement("h3");
|
2017-04-14 14:37:09 +00:00
|
|
|
|
h3.textContent = longty;
|
|
|
|
|
div.appendChild(h3);
|
2018-11-16 15:31:07 +00:00
|
|
|
|
var ul = document.createElement("ul");
|
2015-03-05 07:35:43 +00:00
|
|
|
|
|
2020-12-30 15:36:08 +00:00
|
|
|
|
for (var i = 0, len = filtered.length; i < len; ++i) {
|
2015-03-05 07:35:43 +00:00
|
|
|
|
var item = filtered[i];
|
|
|
|
|
var name = item[0];
|
|
|
|
|
var desc = item[1]; // can be null
|
|
|
|
|
|
|
|
|
|
var klass = shortty;
|
2015-05-22 12:14:28 +00:00
|
|
|
|
if (name === current.name && shortty === current.ty) {
|
2018-11-16 15:31:07 +00:00
|
|
|
|
klass += " current";
|
2015-03-05 07:35:43 +00:00
|
|
|
|
}
|
|
|
|
|
var path;
|
2018-11-16 15:31:07 +00:00
|
|
|
|
if (shortty === "mod") {
|
|
|
|
|
path = name + "/index.html";
|
2015-03-05 07:35:43 +00:00
|
|
|
|
} else {
|
2018-11-16 15:31:07 +00:00
|
|
|
|
path = shortty + "." + name + ".html";
|
2015-03-05 07:35:43 +00:00
|
|
|
|
}
|
2018-11-16 15:31:07 +00:00
|
|
|
|
var link = document.createElement("a");
|
2017-04-14 14:37:09 +00:00
|
|
|
|
link.href = current.relpath + path;
|
|
|
|
|
link.title = desc;
|
|
|
|
|
link.className = klass;
|
|
|
|
|
link.textContent = name;
|
2018-11-16 15:31:07 +00:00
|
|
|
|
var li = document.createElement("li");
|
2017-04-14 14:37:09 +00:00
|
|
|
|
li.appendChild(link);
|
|
|
|
|
ul.appendChild(li);
|
2015-03-05 07:35:43 +00:00
|
|
|
|
}
|
2017-04-14 14:37:09 +00:00
|
|
|
|
div.appendChild(ul);
|
2021-11-04 15:27:02 +00:00
|
|
|
|
others.appendChild(div);
|
2015-03-05 07:35:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-02 14:35:48 +00:00
|
|
|
|
if (sidebar) {
|
2021-11-04 15:27:02 +00:00
|
|
|
|
others = document.createElement("div");
|
|
|
|
|
others.className = "others";
|
|
|
|
|
sidebar.appendChild(others);
|
|
|
|
|
|
2021-05-31 09:51:22 +00:00
|
|
|
|
var isModule = hasClass(document.body, "mod");
|
2021-05-02 14:35:48 +00:00
|
|
|
|
if (!isModule) {
|
|
|
|
|
block("primitive", "Primitive Types");
|
|
|
|
|
block("mod", "Modules");
|
|
|
|
|
block("macro", "Macros");
|
|
|
|
|
block("struct", "Structs");
|
|
|
|
|
block("enum", "Enums");
|
|
|
|
|
block("union", "Unions");
|
|
|
|
|
block("constant", "Constants");
|
|
|
|
|
block("static", "Statics");
|
|
|
|
|
block("trait", "Traits");
|
|
|
|
|
block("fn", "Functions");
|
|
|
|
|
block("type", "Type Definitions");
|
|
|
|
|
block("foreigntype", "Foreign Types");
|
|
|
|
|
block("keyword", "Keywords");
|
|
|
|
|
block("traitalias", "Trait Aliases");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// `crates{version}.js` should always be loaded before this script, so we can use
|
|
|
|
|
// it safely.
|
|
|
|
|
addSidebarCrates(window.ALL_CRATES);
|
|
|
|
|
}
|
2020-05-17 12:57:19 +00:00
|
|
|
|
};
|
2015-03-05 07:35:43 +00:00
|
|
|
|
|
2014-05-21 23:41:58 +00:00
|
|
|
|
window.register_implementors = function(imp) {
|
2018-11-16 15:31:07 +00:00
|
|
|
|
var implementors = document.getElementById("implementors-list");
|
|
|
|
|
var synthetic_implementors = document.getElementById("synthetic-implementors-list");
|
2018-02-15 23:45:52 +00:00
|
|
|
|
|
2020-01-28 12:48:08 +00:00
|
|
|
|
if (synthetic_implementors) {
|
|
|
|
|
// This `inlined_types` variable is used to avoid having the same implementation
|
|
|
|
|
// showing up twice. For example "String" in the "Sync" doc page.
|
|
|
|
|
//
|
|
|
|
|
// By the way, this is only used by and useful for traits implemented automatically
|
|
|
|
|
// (like "Send" and "Sync").
|
|
|
|
|
var inlined_types = new Set();
|
|
|
|
|
onEachLazy(synthetic_implementors.getElementsByClassName("impl"), function(el) {
|
2021-04-27 22:47:49 +00:00
|
|
|
|
var aliases = el.getAttribute("data-aliases");
|
2020-01-28 12:48:08 +00:00
|
|
|
|
if (!aliases) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
aliases.split(",").forEach(function(alias) {
|
|
|
|
|
inlined_types.add(alias);
|
|
|
|
|
});
|
2020-01-13 22:28:34 +00:00
|
|
|
|
});
|
2020-01-28 12:48:08 +00:00
|
|
|
|
}
|
2020-01-13 22:28:34 +00:00
|
|
|
|
|
2021-07-10 12:58:36 +00:00
|
|
|
|
var currentNbImpls = implementors.getElementsByClassName("impl").length;
|
|
|
|
|
var traitName = document.querySelector("h1.fqn > .in-band > .trait").textContent;
|
|
|
|
|
var baseIdName = "impl-" + traitName + "-";
|
2014-05-21 23:41:58 +00:00
|
|
|
|
var libs = Object.getOwnPropertyNames(imp);
|
2020-12-30 15:36:08 +00:00
|
|
|
|
for (var i = 0, llength = libs.length; i < llength; ++i) {
|
2021-01-18 11:03:53 +00:00
|
|
|
|
if (libs[i] === window.currentCrate) { continue; }
|
2014-05-28 00:52:40 +00:00
|
|
|
|
var structs = imp[libs[i]];
|
2018-02-10 19:34:46 +00:00
|
|
|
|
|
|
|
|
|
struct_loop:
|
2020-12-30 15:36:08 +00:00
|
|
|
|
for (var j = 0, slength = structs.length; j < slength; ++j) {
|
Generate documentation for auto-trait impls
A new section is added to both both struct and trait doc pages.
On struct/enum pages, a new 'Auto Trait Implementations' section displays any
synthetic implementations for auto traits. Currently, this is only done
for Send and Sync.
On trait pages, a new 'Auto Implementors' section displays all types
which automatically implement the trait. Effectively, this is a list of
all public types in the standard library.
Synthesized impls for a particular auto trait ('synthetic impls') take
into account generic bounds. For example, a type 'struct Foo<T>(T)' will
have 'impl<T> Send for Foo<T> where T: Send' generated for it.
Manual implementations of auto traits are also taken into account. If we have
the following types:
'struct Foo<T>(T)'
'struct Wrapper<T>(Foo<T>)'
'unsafe impl<T> Send for Wrapper<T>' // pretend that Wrapper<T> makes
this sound somehow
Then Wrapper will have the following impl generated:
'impl<T> Send for Wrapper<T>'
reflecting the fact that 'T: Send' need not hold for 'Wrapper<T>: Send'
to hold
Lifetimes, HRTBS, and projections (e.g. '<T as Iterator>::Item') are
taken into account by synthetic impls
However, if a type can *never* implement a particular auto trait
(e.g. 'struct MyStruct<T>(*const T)'), then a negative impl will be
generated (in this case, 'impl<T> !Send for MyStruct<T>')
All of this means that a user should be able to copy-paste a synthetic
impl into their code, without any observable changes in behavior
(assuming the rest of the program remains unchanged).
2017-11-22 21:16:55 +00:00
|
|
|
|
var struct = structs[j];
|
2018-02-15 23:45:52 +00:00
|
|
|
|
|
Generate documentation for auto-trait impls
A new section is added to both both struct and trait doc pages.
On struct/enum pages, a new 'Auto Trait Implementations' section displays any
synthetic implementations for auto traits. Currently, this is only done
for Send and Sync.
On trait pages, a new 'Auto Implementors' section displays all types
which automatically implement the trait. Effectively, this is a list of
all public types in the standard library.
Synthesized impls for a particular auto trait ('synthetic impls') take
into account generic bounds. For example, a type 'struct Foo<T>(T)' will
have 'impl<T> Send for Foo<T> where T: Send' generated for it.
Manual implementations of auto traits are also taken into account. If we have
the following types:
'struct Foo<T>(T)'
'struct Wrapper<T>(Foo<T>)'
'unsafe impl<T> Send for Wrapper<T>' // pretend that Wrapper<T> makes
this sound somehow
Then Wrapper will have the following impl generated:
'impl<T> Send for Wrapper<T>'
reflecting the fact that 'T: Send' need not hold for 'Wrapper<T>: Send'
to hold
Lifetimes, HRTBS, and projections (e.g. '<T as Iterator>::Item') are
taken into account by synthetic impls
However, if a type can *never* implement a particular auto trait
(e.g. 'struct MyStruct<T>(*const T)'), then a negative impl will be
generated (in this case, 'impl<T> !Send for MyStruct<T>')
All of this means that a user should be able to copy-paste a synthetic
impl into their code, without any observable changes in behavior
(assuming the rest of the program remains unchanged).
2017-11-22 21:16:55 +00:00
|
|
|
|
var list = struct.synthetic ? synthetic_implementors : implementors;
|
|
|
|
|
|
2018-02-15 23:45:52 +00:00
|
|
|
|
if (struct.synthetic) {
|
2020-12-30 15:36:08 +00:00
|
|
|
|
for (var k = 0, stlength = struct.types.length; k < stlength; k++) {
|
2020-01-13 22:28:34 +00:00
|
|
|
|
if (inlined_types.has(struct.types[k])) {
|
2018-02-15 23:45:52 +00:00
|
|
|
|
continue struct_loop;
|
|
|
|
|
}
|
2020-01-13 22:28:34 +00:00
|
|
|
|
inlined_types.add(struct.types[k]);
|
Generate documentation for auto-trait impls
A new section is added to both both struct and trait doc pages.
On struct/enum pages, a new 'Auto Trait Implementations' section displays any
synthetic implementations for auto traits. Currently, this is only done
for Send and Sync.
On trait pages, a new 'Auto Implementors' section displays all types
which automatically implement the trait. Effectively, this is a list of
all public types in the standard library.
Synthesized impls for a particular auto trait ('synthetic impls') take
into account generic bounds. For example, a type 'struct Foo<T>(T)' will
have 'impl<T> Send for Foo<T> where T: Send' generated for it.
Manual implementations of auto traits are also taken into account. If we have
the following types:
'struct Foo<T>(T)'
'struct Wrapper<T>(Foo<T>)'
'unsafe impl<T> Send for Wrapper<T>' // pretend that Wrapper<T> makes
this sound somehow
Then Wrapper will have the following impl generated:
'impl<T> Send for Wrapper<T>'
reflecting the fact that 'T: Send' need not hold for 'Wrapper<T>: Send'
to hold
Lifetimes, HRTBS, and projections (e.g. '<T as Iterator>::Item') are
taken into account by synthetic impls
However, if a type can *never* implement a particular auto trait
(e.g. 'struct MyStruct<T>(*const T)'), then a negative impl will be
generated (in this case, 'impl<T> !Send for MyStruct<T>')
All of this means that a user should be able to copy-paste a synthetic
impl into their code, without any observable changes in behavior
(assuming the rest of the program remains unchanged).
2017-11-22 21:16:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-25 21:41:57 +00:00
|
|
|
|
var code = document.createElement("h3");
|
Generate documentation for auto-trait impls
A new section is added to both both struct and trait doc pages.
On struct/enum pages, a new 'Auto Trait Implementations' section displays any
synthetic implementations for auto traits. Currently, this is only done
for Send and Sync.
On trait pages, a new 'Auto Implementors' section displays all types
which automatically implement the trait. Effectively, this is a list of
all public types in the standard library.
Synthesized impls for a particular auto trait ('synthetic impls') take
into account generic bounds. For example, a type 'struct Foo<T>(T)' will
have 'impl<T> Send for Foo<T> where T: Send' generated for it.
Manual implementations of auto traits are also taken into account. If we have
the following types:
'struct Foo<T>(T)'
'struct Wrapper<T>(Foo<T>)'
'unsafe impl<T> Send for Wrapper<T>' // pretend that Wrapper<T> makes
this sound somehow
Then Wrapper will have the following impl generated:
'impl<T> Send for Wrapper<T>'
reflecting the fact that 'T: Send' need not hold for 'Wrapper<T>: Send'
to hold
Lifetimes, HRTBS, and projections (e.g. '<T as Iterator>::Item') are
taken into account by synthetic impls
However, if a type can *never* implement a particular auto trait
(e.g. 'struct MyStruct<T>(*const T)'), then a negative impl will be
generated (in this case, 'impl<T> !Send for MyStruct<T>')
All of this means that a user should be able to copy-paste a synthetic
impl into their code, without any observable changes in behavior
(assuming the rest of the program remains unchanged).
2017-11-22 21:16:55 +00:00
|
|
|
|
code.innerHTML = struct.text;
|
2021-07-25 21:41:57 +00:00
|
|
|
|
addClass(code, "code-header");
|
2021-07-10 12:58:36 +00:00
|
|
|
|
addClass(code, "in-band");
|
2017-04-14 14:37:09 +00:00
|
|
|
|
|
2020-12-31 12:21:27 +00:00
|
|
|
|
onEachLazy(code.getElementsByTagName("a"), function(elem) {
|
|
|
|
|
var href = elem.getAttribute("href");
|
|
|
|
|
|
2018-11-16 15:31:07 +00:00
|
|
|
|
if (href && href.indexOf("http") !== 0) {
|
2021-01-18 11:03:53 +00:00
|
|
|
|
elem.setAttribute("href", window.rootPath + href);
|
2014-06-01 17:17:30 +00:00
|
|
|
|
}
|
2020-12-31 12:21:27 +00:00
|
|
|
|
});
|
|
|
|
|
|
2021-07-10 12:58:36 +00:00
|
|
|
|
var currentId = baseIdName + currentNbImpls;
|
|
|
|
|
var anchor = document.createElement("a");
|
|
|
|
|
anchor.href = "#" + currentId;
|
|
|
|
|
addClass(anchor, "anchor");
|
|
|
|
|
|
|
|
|
|
var display = document.createElement("div");
|
|
|
|
|
display.id = currentId;
|
2018-07-01 14:11:14 +00:00
|
|
|
|
addClass(display, "impl");
|
2021-07-10 12:58:36 +00:00
|
|
|
|
display.appendChild(anchor);
|
|
|
|
|
display.appendChild(code);
|
2018-07-01 14:11:14 +00:00
|
|
|
|
list.appendChild(display);
|
2021-07-10 12:58:36 +00:00
|
|
|
|
currentNbImpls += 1;
|
2014-05-21 23:41:58 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
if (window.pending_implementors) {
|
|
|
|
|
window.register_implementors(window.pending_implementors);
|
|
|
|
|
}
|
2014-05-24 03:17:27 +00:00
|
|
|
|
|
2015-05-07 07:53:21 +00:00
|
|
|
|
function labelForToggleButton(sectionIsCollapsed) {
|
|
|
|
|
if (sectionIsCollapsed) {
|
|
|
|
|
// button will expand the section
|
|
|
|
|
return "+";
|
|
|
|
|
}
|
2015-05-22 12:14:28 +00:00
|
|
|
|
// button will collapse the section
|
2021-03-05 17:04:33 +00:00
|
|
|
|
// note that this text is also set in the HTML template in ../render/mod.rs
|
2018-11-16 15:31:07 +00:00
|
|
|
|
return "\u2212"; // "\u2212" is "−" minus sign
|
2015-05-07 07:53:21 +00:00
|
|
|
|
}
|
2015-05-07 08:17:10 +00:00
|
|
|
|
|
2021-05-08 12:21:57 +00:00
|
|
|
|
function toggleAllDocs() {
|
2020-08-29 10:38:50 +00:00
|
|
|
|
var innerToggle = document.getElementById(toggleAllDocsId);
|
2018-11-26 16:17:38 +00:00
|
|
|
|
if (!innerToggle) {
|
2018-04-25 17:50:32 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2021-05-08 12:21:57 +00:00
|
|
|
|
var sectionIsCollapsed = false;
|
2018-11-26 16:17:38 +00:00
|
|
|
|
if (hasClass(innerToggle, "will-expand")) {
|
|
|
|
|
removeClass(innerToggle, "will-expand");
|
2021-05-08 12:21:57 +00:00
|
|
|
|
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), function(e) {
|
|
|
|
|
if (!hasClass(e, "type-contents-toggle")) {
|
|
|
|
|
e.open = true;
|
|
|
|
|
}
|
2017-04-14 14:37:09 +00:00
|
|
|
|
});
|
2018-11-26 16:17:38 +00:00
|
|
|
|
innerToggle.title = "collapse all docs";
|
2015-05-07 07:53:21 +00:00
|
|
|
|
} else {
|
2018-11-26 16:17:38 +00:00
|
|
|
|
addClass(innerToggle, "will-expand");
|
2021-05-08 12:21:57 +00:00
|
|
|
|
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), function(e) {
|
2021-11-29 16:14:05 +00:00
|
|
|
|
if (e.parentNode.id !== MAIN_ID ||
|
2021-05-08 12:21:57 +00:00
|
|
|
|
(!hasClass(e, "implementors-toggle") &&
|
|
|
|
|
!hasClass(e, "type-contents-toggle")))
|
|
|
|
|
{
|
|
|
|
|
e.open = false;
|
2019-02-04 13:59:06 +00:00
|
|
|
|
}
|
2017-04-14 14:37:09 +00:00
|
|
|
|
});
|
2021-05-08 12:21:57 +00:00
|
|
|
|
sectionIsCollapsed = true;
|
2018-11-26 16:17:38 +00:00
|
|
|
|
innerToggle.title = "expand all docs";
|
2015-04-22 16:50:19 +00:00
|
|
|
|
}
|
2021-05-08 12:21:57 +00:00
|
|
|
|
innerToggle.children[0].innerText = labelForToggleButton(sectionIsCollapsed);
|
2016-05-21 02:21:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-14 14:37:09 +00:00
|
|
|
|
function insertAfter(newNode, referenceNode) {
|
|
|
|
|
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
|
|
|
|
|
}
|
2014-07-31 01:31:34 +00:00
|
|
|
|
|
2020-05-17 12:49:04 +00:00
|
|
|
|
(function() {
|
2020-08-29 10:38:50 +00:00
|
|
|
|
var toggles = document.getElementById(toggleAllDocsId);
|
2020-08-28 11:30:21 +00:00
|
|
|
|
if (toggles) {
|
|
|
|
|
toggles.onclick = toggleAllDocs;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-23 21:14:43 +00:00
|
|
|
|
var hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true";
|
2021-06-13 05:19:26 +00:00
|
|
|
|
var hideImplementations = getSettingValue("auto-hide-trait-implementations") === "true";
|
2021-04-12 20:18:36 +00:00
|
|
|
|
var hideLargeItemContents = getSettingValue("auto-hide-large-items") !== "false";
|
2021-04-18 21:33:33 +00:00
|
|
|
|
|
2021-06-13 05:19:26 +00:00
|
|
|
|
function setImplementorsTogglesOpen(id, open) {
|
2021-05-22 04:24:03 +00:00
|
|
|
|
var list = document.getElementById(id);
|
|
|
|
|
if (list !== null) {
|
|
|
|
|
onEachLazy(list.getElementsByClassName("implementors-toggle"), function(e) {
|
2021-06-13 05:19:26 +00:00
|
|
|
|
e.open = open;
|
2021-05-22 04:24:03 +00:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-13 05:19:26 +00:00
|
|
|
|
if (hideImplementations) {
|
|
|
|
|
setImplementorsTogglesOpen("trait-implementations-list", false);
|
|
|
|
|
setImplementorsTogglesOpen("blanket-implementations-list", false);
|
2021-05-22 04:24:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), function (e) {
|
|
|
|
|
if (!hideLargeItemContents && hasClass(e, "type-contents-toggle")) {
|
2021-04-18 06:43:20 +00:00
|
|
|
|
e.open = true;
|
|
|
|
|
}
|
2021-05-10 23:41:41 +00:00
|
|
|
|
if (hideMethodDocs && hasClass(e, "method-toggle")) {
|
|
|
|
|
e.open = false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-18 06:43:20 +00:00
|
|
|
|
});
|
2020-05-17 12:49:04 +00:00
|
|
|
|
|
2021-01-23 13:55:24 +00:00
|
|
|
|
var pageId = getPageId();
|
2020-06-27 15:56:13 +00:00
|
|
|
|
if (pageId !== null) {
|
|
|
|
|
expandSection(pageId);
|
|
|
|
|
}
|
2020-05-17 12:49:04 +00:00
|
|
|
|
}());
|
2017-04-14 14:37:09 +00:00
|
|
|
|
|
2020-05-17 12:49:04 +00:00
|
|
|
|
(function() {
|
|
|
|
|
// To avoid checking on "rustdoc-line-numbers" value on every loop...
|
|
|
|
|
var lineNumbersFunc = function() {};
|
2020-09-23 21:14:43 +00:00
|
|
|
|
if (getSettingValue("line-numbers") === "true") {
|
2020-05-17 12:49:04 +00:00
|
|
|
|
lineNumbersFunc = function(x) {
|
|
|
|
|
var count = x.textContent.split("\n").length;
|
|
|
|
|
var elems = [];
|
|
|
|
|
for (var i = 0; i < count; ++i) {
|
|
|
|
|
elems.push(i + 1);
|
|
|
|
|
}
|
|
|
|
|
var node = document.createElement("pre");
|
|
|
|
|
addClass(node, "line-number");
|
|
|
|
|
node.innerHTML = elems.join("\n");
|
|
|
|
|
x.parentNode.insertBefore(node, x);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
onEachLazy(document.getElementsByClassName("rust-example-rendered"), function(e) {
|
|
|
|
|
if (hasClass(e, "compile_fail")) {
|
2020-05-17 13:34:59 +00:00
|
|
|
|
e.addEventListener("mouseover", function() {
|
2020-05-17 12:49:04 +00:00
|
|
|
|
this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00";
|
|
|
|
|
});
|
2020-05-17 13:34:59 +00:00
|
|
|
|
e.addEventListener("mouseout", function() {
|
2020-05-17 12:49:04 +00:00
|
|
|
|
this.parentElement.previousElementSibling.childNodes[0].style.color = "";
|
|
|
|
|
});
|
|
|
|
|
} else if (hasClass(e, "ignore")) {
|
2020-05-17 13:34:59 +00:00
|
|
|
|
e.addEventListener("mouseover", function() {
|
2020-05-17 12:49:04 +00:00
|
|
|
|
this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200";
|
|
|
|
|
});
|
2020-05-17 13:34:59 +00:00
|
|
|
|
e.addEventListener("mouseout", function() {
|
2020-05-17 12:49:04 +00:00
|
|
|
|
this.parentElement.previousElementSibling.childNodes[0].style.color = "";
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
lineNumbersFunc(e);
|
|
|
|
|
});
|
|
|
|
|
}());
|
2017-11-10 18:40:46 +00:00
|
|
|
|
|
2021-05-09 18:21:38 +00:00
|
|
|
|
function handleClick(id, f) {
|
|
|
|
|
var elem = document.getElementById(id);
|
|
|
|
|
if (elem) {
|
|
|
|
|
elem.addEventListener("click", f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
handleClick("help-button", function(ev) {
|
|
|
|
|
displayHelp(true, ev);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onEachLazy(document.getElementsByTagName("a"), function(el) {
|
|
|
|
|
// For clicks on internal links (<A> tags with a hash property), we expand the section we're
|
|
|
|
|
// jumping to *before* jumping there. We can't do this in onHashChange, because it changes
|
|
|
|
|
// the height of the document so we wind up scrolled to the wrong place.
|
|
|
|
|
if (el.hash) {
|
|
|
|
|
el.addEventListener("click", function() {
|
|
|
|
|
expandSection(el.hash.slice(1));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2021-11-21 08:24:38 +00:00
|
|
|
|
onEachLazy(document.querySelectorAll(".rustdoc-toggle > summary:not(.hideme)"), function(el) {
|
|
|
|
|
el.addEventListener("click", function(e) {
|
2021-11-24 18:43:58 +00:00
|
|
|
|
if (e.target.tagName != "SUMMARY" && e.target.tagName != "A") {
|
2021-11-21 08:24:38 +00:00
|
|
|
|
e.preventDefault();
|
|
|
|
|
}
|
2021-11-22 08:49:57 +00:00
|
|
|
|
});
|
2021-11-21 08:24:38 +00:00
|
|
|
|
});
|
|
|
|
|
|
2020-08-09 19:09:05 +00:00
|
|
|
|
onEachLazy(document.getElementsByClassName("notable-traits"), function(e) {
|
2020-07-06 19:53:44 +00:00
|
|
|
|
e.onclick = function() {
|
2020-08-09 19:09:05 +00:00
|
|
|
|
this.getElementsByClassName('notable-traits-tooltiptext')[0]
|
2020-07-15 15:58:10 +00:00
|
|
|
|
.classList.toggle("force-tooltip");
|
2020-07-06 19:53:44 +00:00
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
2017-12-05 23:42:33 +00:00
|
|
|
|
var sidebar_menu = document.getElementsByClassName("sidebar-menu")[0];
|
|
|
|
|
if (sidebar_menu) {
|
|
|
|
|
sidebar_menu.onclick = function() {
|
2018-11-16 15:31:07 +00:00
|
|
|
|
var sidebar = document.getElementsByClassName("sidebar")[0];
|
2021-05-09 20:49:22 +00:00
|
|
|
|
if (hasClass(sidebar, "mobile")) {
|
2017-12-05 23:42:33 +00:00
|
|
|
|
hideSidebar();
|
|
|
|
|
} else {
|
|
|
|
|
showSidebar();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-14 11:56:15 +00:00
|
|
|
|
var buildHelperPopup = function() {
|
2019-10-24 22:35:45 +00:00
|
|
|
|
var popup = document.createElement("aside");
|
|
|
|
|
addClass(popup, "hidden");
|
|
|
|
|
popup.id = "help";
|
|
|
|
|
|
2021-05-09 18:21:38 +00:00
|
|
|
|
popup.addEventListener("click", function(ev) {
|
|
|
|
|
if (ev.target === popup) {
|
|
|
|
|
// Clicked the blurred zone outside the help popup; dismiss help.
|
|
|
|
|
displayHelp(false, ev);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2020-10-19 11:44:27 +00:00
|
|
|
|
var book_info = document.createElement("span");
|
2021-09-15 11:37:29 +00:00
|
|
|
|
book_info.className = "top";
|
2020-10-19 11:44:27 +00:00
|
|
|
|
book_info.innerHTML = "You can find more information in \
|
|
|
|
|
<a href=\"https://doc.rust-lang.org/rustdoc/\">the rustdoc book</a>.";
|
|
|
|
|
|
2019-10-24 22:35:45 +00:00
|
|
|
|
var container = document.createElement("div");
|
|
|
|
|
var shortcuts = [
|
|
|
|
|
["?", "Show this help dialog"],
|
|
|
|
|
["S", "Focus the search field"],
|
2020-11-05 13:24:45 +00:00
|
|
|
|
["T", "Focus the theme picker menu"],
|
2019-10-24 22:35:45 +00:00
|
|
|
|
["↑", "Move up in search results"],
|
|
|
|
|
["↓", "Move down in search results"],
|
2021-05-09 19:56:21 +00:00
|
|
|
|
["← / →", "Switch result tab (when results focused)"],
|
2019-10-24 22:35:45 +00:00
|
|
|
|
["⏎", "Go to active search result"],
|
|
|
|
|
["+", "Expand all sections"],
|
|
|
|
|
["-", "Collapse all sections"],
|
2021-02-15 09:11:37 +00:00
|
|
|
|
].map(function(x) {
|
|
|
|
|
return "<dt>" +
|
|
|
|
|
x[0].split(" ")
|
|
|
|
|
.map(function(y, index) {
|
|
|
|
|
return (index & 1) === 0 ? "<kbd>" + y + "</kbd>" : " " + y + " ";
|
|
|
|
|
})
|
|
|
|
|
.join("") + "</dt><dd>" + x[1] + "</dd>";
|
|
|
|
|
}).join("");
|
2019-10-24 22:35:45 +00:00
|
|
|
|
var div_shortcuts = document.createElement("div");
|
|
|
|
|
addClass(div_shortcuts, "shortcuts");
|
|
|
|
|
div_shortcuts.innerHTML = "<h2>Keyboard Shortcuts</h2><dl>" + shortcuts + "</dl></div>";
|
|
|
|
|
|
|
|
|
|
var infos = [
|
|
|
|
|
"Prefix searches with a type followed by a colon (e.g., <code>fn:</code>) to \
|
2020-08-27 10:56:43 +00:00
|
|
|
|
restrict the search to a given item kind.",
|
|
|
|
|
"Accepted kinds are: <code>fn</code>, <code>mod</code>, <code>struct</code>, \
|
2019-10-24 22:35:45 +00:00
|
|
|
|
<code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, \
|
|
|
|
|
and <code>const</code>.",
|
2020-01-12 23:37:47 +00:00
|
|
|
|
"Search functions by type signature (e.g., <code>vec -> usize</code> or \
|
|
|
|
|
<code>* -> vec</code>)",
|
2019-10-24 22:35:45 +00:00
|
|
|
|
"Search multiple things at once by splitting your query with comma (e.g., \
|
|
|
|
|
<code>str,u8</code> or <code>String,struct:Vec,test</code>)",
|
|
|
|
|
"You can look for items with an exact name by putting double quotes around \
|
|
|
|
|
your request: <code>\"string\"</code>",
|
|
|
|
|
"Look for items inside another one by searching for a path: <code>vec::Vec</code>",
|
2021-02-15 09:11:37 +00:00
|
|
|
|
].map(function(x) {
|
|
|
|
|
return "<p>" + x + "</p>";
|
|
|
|
|
}).join("");
|
2019-10-24 22:35:45 +00:00
|
|
|
|
var div_infos = document.createElement("div");
|
|
|
|
|
addClass(div_infos, "infos");
|
|
|
|
|
div_infos.innerHTML = "<h2>Search Tricks</h2>" + infos;
|
|
|
|
|
|
2020-10-19 11:44:27 +00:00
|
|
|
|
container.appendChild(book_info);
|
2019-10-24 22:35:45 +00:00
|
|
|
|
container.appendChild(div_shortcuts);
|
|
|
|
|
container.appendChild(div_infos);
|
|
|
|
|
|
2021-09-15 11:37:29 +00:00
|
|
|
|
var rustdoc_version = document.createElement("span");
|
|
|
|
|
rustdoc_version.className = "bottom";
|
|
|
|
|
var rustdoc_version_code = document.createElement("code");
|
2021-11-24 03:22:29 +00:00
|
|
|
|
rustdoc_version_code.innerText = "rustdoc " + getVar("rustdoc-version");
|
2021-09-15 11:37:29 +00:00
|
|
|
|
rustdoc_version.appendChild(rustdoc_version_code);
|
|
|
|
|
|
|
|
|
|
container.appendChild(rustdoc_version);
|
|
|
|
|
|
2019-10-24 22:35:45 +00:00
|
|
|
|
popup.appendChild(container);
|
2021-09-30 02:23:02 +00:00
|
|
|
|
insertAfter(popup, document.querySelector("main"));
|
2020-08-27 11:34:35 +00:00
|
|
|
|
// So that it's only built once and then it'll do nothing when called!
|
|
|
|
|
buildHelperPopup = function() {};
|
2021-05-14 11:56:15 +00:00
|
|
|
|
};
|
2019-10-24 22:35:45 +00:00
|
|
|
|
|
2019-12-15 20:27:25 +00:00
|
|
|
|
onHashChange(null);
|
2021-05-09 18:21:38 +00:00
|
|
|
|
window.addEventListener("hashchange", onHashChange);
|
2021-04-13 07:35:36 +00:00
|
|
|
|
searchState.setup();
|
2014-01-15 01:09:50 +00:00
|
|
|
|
}());
|
2021-03-31 20:13:47 +00:00
|
|
|
|
|
2021-04-30 09:42:07 +00:00
|
|
|
|
(function () {
|
|
|
|
|
var reset_button_timeout = null;
|
|
|
|
|
|
2021-04-30 10:06:15 +00:00
|
|
|
|
window.copy_path = function(but) {
|
2021-04-30 09:42:07 +00:00
|
|
|
|
var parent = but.parentElement;
|
|
|
|
|
var path = [];
|
|
|
|
|
|
|
|
|
|
onEach(parent.childNodes, function(child) {
|
|
|
|
|
if (child.tagName === 'A') {
|
|
|
|
|
path.push(child.textContent);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var el = document.createElement('textarea');
|
2021-07-16 03:45:27 +00:00
|
|
|
|
el.value = path.join('::');
|
2021-04-30 09:42:07 +00:00
|
|
|
|
el.setAttribute('readonly', '');
|
|
|
|
|
// To not make it appear on the screen.
|
|
|
|
|
el.style.position = 'absolute';
|
|
|
|
|
el.style.left = '-9999px';
|
2021-04-30 08:18:14 +00:00
|
|
|
|
|
2021-04-30 09:42:07 +00:00
|
|
|
|
document.body.appendChild(el);
|
|
|
|
|
el.select();
|
|
|
|
|
document.execCommand('copy');
|
|
|
|
|
document.body.removeChild(el);
|
2021-03-31 20:13:47 +00:00
|
|
|
|
|
2021-05-09 18:41:24 +00:00
|
|
|
|
// There is always one children, but multiple childNodes.
|
|
|
|
|
but.children[0].style.display = 'none';
|
|
|
|
|
|
|
|
|
|
var tmp;
|
|
|
|
|
if (but.childNodes.length < 2) {
|
|
|
|
|
tmp = document.createTextNode('✓');
|
|
|
|
|
but.appendChild(tmp);
|
|
|
|
|
} else {
|
|
|
|
|
onEachLazy(but.childNodes, function(e) {
|
|
|
|
|
if (e.nodeType === Node.TEXT_NODE) {
|
|
|
|
|
tmp = e;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
tmp.textContent = '✓';
|
|
|
|
|
}
|
2021-04-30 09:42:07 +00:00
|
|
|
|
|
|
|
|
|
if (reset_button_timeout !== null) {
|
|
|
|
|
window.clearTimeout(reset_button_timeout);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function reset_button() {
|
2021-05-09 18:41:24 +00:00
|
|
|
|
tmp.textContent = '';
|
2021-04-30 09:42:07 +00:00
|
|
|
|
reset_button_timeout = null;
|
2021-05-09 18:41:24 +00:00
|
|
|
|
but.children[0].style.display = "";
|
2021-03-31 20:13:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-04-30 09:42:07 +00:00
|
|
|
|
reset_button_timeout = window.setTimeout(reset_button, 1000);
|
2021-04-30 10:06:15 +00:00
|
|
|
|
};
|
2021-04-30 09:42:07 +00:00
|
|
|
|
}());
|