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-01-18 11:03:53 +00:00
|
|
|
|
(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;
|
Load rustdoc's JS search index on-demand.
Instead of being loaded on every page, the JS search index is now
loaded when either (a) there is a `?search=` param, or (b) the search
input is focused.
This saves both CPU and bandwidth. As of Feb 2021,
https://doc.rust-lang.org/search-index1.50.0.js is 273,838 bytes
gzipped or 2,544,939 bytes uncompressed. Evaluating it takes 445 ms
of CPU time in Chrome 88 on a i7-10710U CPU (out of a total ~2,100
ms page reload).
Generate separate JS file with crate names.
This is much smaller than the full search index, and is used in the "hot
path" to draw the page. In particular it's used to crate the dropdown
for the search bar, and to append a list of crates to the sidebar (on
some pages).
Skip early search that can bypass 500ms timeout.
This was occurring when someone had typed some text during the load of
search-index.js. Their query was usually not ready to execute, and the
search itself is fairly expensive, delaying the overall load, which
delayed the input / keyup events, which delayed eventually executing the
query.
2021-02-20 01:22:30 +00:00
|
|
|
|
window.searchJS = rustdocVars.attributes["data-search-js"].value;
|
2021-04-13 21:59:54 +00:00
|
|
|
|
window.searchIndexJS = rustdocVars.attributes["data-search-index-js"].value;
|
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-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();
|
|
|
|
|
var availableThemes/* INSERT THEMES HERE */;
|
|
|
|
|
|
|
|
|
|
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";
|
2018-11-26 16:17:38 +00:00
|
|
|
|
var main = document.getElementById("main");
|
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];
|
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);
|
|
|
|
|
}
|
|
|
|
|
sidebar.appendChild(div);
|
|
|
|
|
}
|
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-05-02 14:35:48 +00:00
|
|
|
|
sidebar.appendChild(div);
|
2015-03-05 07:35:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-02 14:35:48 +00:00
|
|
|
|
if (sidebar) {
|
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) {
|
|
|
|
|
if (e.parentNode.id !== "main" ||
|
|
|
|
|
(!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));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
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");
|
|
|
|
|
rustdoc_version_code.innerText = "/* INSERT RUSTDOC_VERSION HERE */";
|
|
|
|
|
rustdoc_version.appendChild(rustdoc_version_code);
|
|
|
|
|
|
|
|
|
|
container.appendChild(rustdoc_version);
|
|
|
|
|
|
2019-10-24 22:35:45 +00:00
|
|
|
|
popup.appendChild(container);
|
2021-04-13 06:50:18 +00:00
|
|
|
|
insertAfter(popup, searchState.outputElement());
|
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
|
|
|
|
}());
|