From 5363f350887b1e5b5dd21a86f88c8af9d7fea6da Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:25 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- src/librustdoc/html/static/js/main.js | 184 +++++++++++++++++++++++++++++----- 1 file changed, 160 insertions(+), 24 deletions(-) (limited to 'src/librustdoc/html/static/js/main.js') diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 33480fa41..152116089 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -47,10 +47,8 @@ function blurHandler(event, parentElem, hideCallback) { } } -(function() { - window.rootPath = getVar("root-path"); - window.currentCrate = getVar("current-crate"); -}()); +window.rootPath = getVar("root-path"); +window.currentCrate = getVar("current-crate"); function setMobileTopbar() { // FIXME: It would be nicer to generate this text content directly in HTML, @@ -183,9 +181,9 @@ function browserSupportsHistoryApi() { } // eslint-disable-next-line no-unused-vars -function loadCss(cssFileName) { +function loadCss(cssUrl) { const link = document.createElement("link"); - link.href = resourcePath(cssFileName, ".css"); + link.href = cssUrl; link.type = "text/css"; link.rel = "stylesheet"; document.getElementsByTagName("head")[0].appendChild(link); @@ -204,12 +202,13 @@ function loadCss(cssFileName) { if (event.ctrlKey || event.altKey || event.metaKey) { return; } + window.hideAllModals(false); addClass(getSettingsButton(), "rotate"); event.preventDefault(); // Sending request for the CSS and the JS files at the same time so it will // hopefully be loaded when the JS will generate the settings content. - loadCss("settings"); - loadScript(resourcePath("settings", ".js")); + loadCss(getVar("static-root-path") + getVar("settings-css")); + loadScript(getVar("static-root-path") + getVar("settings-js")); }; window.searchState = { @@ -286,7 +285,7 @@ function loadCss(cssFileName) { function loadSearch() { if (!searchLoaded) { searchLoaded = true; - loadScript(resourcePath("search", ".js")); + loadScript(getVar("static-root-path") + getVar("search-js")); loadScript(resourcePath("search-index", ".js")); } } @@ -303,13 +302,15 @@ function loadCss(cssFileName) { const params = searchState.getQueryStringParams(); if (params.search !== undefined) { - const search = searchState.outputElement(); - search.innerHTML = "

" + - searchState.loadingText + "

"; - searchState.showResults(search); + searchState.setLoadingSearch(); loadSearch(); } }, + setLoadingSearch: () => { + const search = searchState.outputElement(); + search.innerHTML = "

" + searchState.loadingText + "

"; + searchState.showResults(search); + }, }; function getPageId() { @@ -379,7 +380,7 @@ function loadCss(cssFileName) { } ev.preventDefault(); searchState.defocus(); - window.hidePopoverMenus(); + window.hideAllModals(true); // true = reset focus for notable traits } function handleShortcut(ev) { @@ -621,7 +622,7 @@ function loadCss(cssFileName) { const innerToggle = document.getElementById(toggleAllDocsId); removeClass(innerToggle, "will-expand"); onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => { - if (!hasClass(e, "type-contents-toggle")) { + if (!hasClass(e, "type-contents-toggle") && !hasClass(e, "more-examples-toggle")) { e.open = true; } }); @@ -725,12 +726,9 @@ function loadCss(cssFileName) { }); }; - (function() { - // To avoid checking on "rustdoc-line-numbers" value on every loop... - if (getSettingValue("line-numbers") === "true") { - window.rustdoc_add_line_numbers_to_examples(); - } - }()); + if (getSettingValue("line-numbers") === "true") { + window.rustdoc_add_line_numbers_to_examples(); + } let oldSidebarScrollPosition = null; @@ -772,6 +770,7 @@ function loadCss(cssFileName) { }; function showSidebar() { + window.hideAllModals(false); window.rustdocMobileScrollLock(); const sidebar = document.getElementsByClassName("sidebar")[0]; addClass(sidebar, "shown"); @@ -790,6 +789,19 @@ function loadCss(cssFileName) { // we need to switch away from mobile mode and make the main content area scrollable. hideSidebar(); } + if (window.CURRENT_NOTABLE_ELEMENT) { + // As a workaround to the behavior of `contains: layout` used in doc togglers, the + // notable traits popup is positioned using javascript. + // + // This means when the window is resized, we need to redo the layout. + const base = window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE; + const force_visible = base.NOTABLE_FORCE_VISIBLE; + hideNotable(false); + if (force_visible) { + showNotable(base); + base.NOTABLE_FORCE_VISIBLE = true; + } + } }); function handleClick(id, f) { @@ -822,10 +834,123 @@ function loadCss(cssFileName) { }); }); + function showNotable(e) { + if (!window.NOTABLE_TRAITS) { + const data = document.getElementById("notable-traits-data"); + if (data) { + window.NOTABLE_TRAITS = JSON.parse(data.innerText); + } else { + throw new Error("showNotable() called on page without any notable traits!"); + } + } + if (window.CURRENT_NOTABLE_ELEMENT && window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE === e) { + // Make this function idempotent. + return; + } + window.hideAllModals(false); + const ty = e.getAttribute("data-ty"); + const wrapper = document.createElement("div"); + wrapper.innerHTML = "
" + window.NOTABLE_TRAITS[ty] + "
"; + wrapper.className = "notable popover"; + const focusCatcher = document.createElement("div"); + focusCatcher.setAttribute("tabindex", "0"); + focusCatcher.onfocus = hideNotable; + wrapper.appendChild(focusCatcher); + const pos = e.getBoundingClientRect(); + // 5px overlap so that the mouse can easily travel from place to place + wrapper.style.top = (pos.top + window.scrollY + pos.height) + "px"; + wrapper.style.left = 0; + wrapper.style.right = "auto"; + wrapper.style.visibility = "hidden"; + const body = document.getElementsByTagName("body")[0]; + body.appendChild(wrapper); + const wrapperPos = wrapper.getBoundingClientRect(); + // offset so that the arrow points at the center of the "(i)" + const finalPos = pos.left + window.scrollX - wrapperPos.width + 24; + if (finalPos > 0) { + wrapper.style.left = finalPos + "px"; + } else { + wrapper.style.setProperty( + "--popover-arrow-offset", + (wrapperPos.right - pos.right + 4) + "px" + ); + } + wrapper.style.visibility = ""; + window.CURRENT_NOTABLE_ELEMENT = wrapper; + window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE = e; + wrapper.onpointerleave = function(ev) { + // If this is a synthetic touch event, ignore it. A click event will be along shortly. + if (ev.pointerType !== "mouse") { + return; + } + if (!e.NOTABLE_FORCE_VISIBLE && !elemIsInParent(event.relatedTarget, e)) { + hideNotable(true); + } + }; + } + + function notableBlurHandler(event) { + if (window.CURRENT_NOTABLE_ELEMENT && + !elemIsInParent(document.activeElement, window.CURRENT_NOTABLE_ELEMENT) && + !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT) && + !elemIsInParent(document.activeElement, window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE) && + !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE) + ) { + // Work around a difference in the focus behaviour between Firefox, Chrome, and Safari. + // When I click the button on an already-opened notable trait popover, Safari + // hides the popover and then immediately shows it again, while everyone else hides it + // and it stays hidden. + // + // To work around this, make sure the click finishes being dispatched before + // hiding the popover. Since `hideNotable()` is idempotent, this makes Safari behave + // consistently with the other two. + setTimeout(() => hideNotable(false), 0); + } + } + + function hideNotable(focus) { + if (window.CURRENT_NOTABLE_ELEMENT) { + if (window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE) { + if (focus) { + window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.focus(); + } + window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false; + } + const body = document.getElementsByTagName("body")[0]; + body.removeChild(window.CURRENT_NOTABLE_ELEMENT); + window.CURRENT_NOTABLE_ELEMENT = null; + } + } + onEachLazy(document.getElementsByClassName("notable-traits"), e => { e.onclick = function() { - this.getElementsByClassName("notable-traits-tooltiptext")[0] - .classList.toggle("force-tooltip"); + this.NOTABLE_FORCE_VISIBLE = this.NOTABLE_FORCE_VISIBLE ? false : true; + if (window.CURRENT_NOTABLE_ELEMENT && !this.NOTABLE_FORCE_VISIBLE) { + hideNotable(true); + } else { + showNotable(this); + window.CURRENT_NOTABLE_ELEMENT.setAttribute("tabindex", "0"); + window.CURRENT_NOTABLE_ELEMENT.focus(); + window.CURRENT_NOTABLE_ELEMENT.onblur = notableBlurHandler; + } + return false; + }; + e.onpointerenter = function(ev) { + // If this is a synthetic touch event, ignore it. A click event will be along shortly. + if (ev.pointerType !== "mouse") { + return; + } + showNotable(this); + }; + e.onpointerleave = function(ev) { + // If this is a synthetic touch event, ignore it. A click event will be along shortly. + if (ev.pointerType !== "mouse") { + return; + } + if (!this.NOTABLE_FORCE_VISIBLE && + !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT)) { + hideNotable(true); + } }; }); @@ -928,6 +1053,17 @@ function loadCss(cssFileName) { return container; } + /** + * Hide popover menus, notable trait tooltips, and the sidebar (if applicable). + * + * Pass "true" to reset focus for notable traits. + */ + window.hideAllModals = function(switchFocus) { + hideSidebar(); + window.hidePopoverMenus(); + hideNotable(switchFocus); + }; + /** * Hide all the popover menus. */ @@ -959,7 +1095,7 @@ function loadCss(cssFileName) { function showHelp() { const menu = getHelpMenu(true); if (menu.style.display === "none") { - window.hidePopoverMenus(); + window.hideAllModals(); menu.style.display = ""; } } -- cgit v1.2.3