diff options
Diffstat (limited to 'src/librustdoc/html/static/js')
| -rw-r--r-- | src/librustdoc/html/static/js/main.js | 50 | ||||
| -rw-r--r-- | src/librustdoc/html/static/js/rustdoc.d.ts | 7 | ||||
| -rw-r--r-- | src/librustdoc/html/static/js/search.js | 97 | ||||
| -rw-r--r-- | src/librustdoc/html/static/js/storage.js | 2 | 
4 files changed, 83 insertions, 73 deletions
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 20fc6b75d37..4fcba5f120b 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -407,9 +407,7 @@ function preLoadCss(cssUrl) { function loadSearch() { if (!searchLoaded) { searchLoaded = true; - // @ts-expect-error window.rr_ = data => { - // @ts-expect-error window.searchIndex = data; }; if (!window.StringdexOnload) { @@ -1277,13 +1275,11 @@ function preLoadCss(cssUrl) { } window.addEventListener("resize", () => { - // @ts-expect-error if (window.CURRENT_TOOLTIP_ELEMENT) { // As a workaround to the behavior of `contains: layout` used in doc togglers, // tooltip popovers are positioned using javascript. // // This means when the window is resized, we need to redo the layout. - // @ts-expect-error const base = window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE; const force_visible = base.TOOLTIP_FORCE_VISIBLE; hideTooltip(false); @@ -1329,11 +1325,9 @@ function preLoadCss(cssUrl) { */ function showTooltip(e) { const notable_ty = e.getAttribute("data-notable-ty"); - // @ts-expect-error if (!window.NOTABLE_TRAITS && notable_ty) { const data = document.getElementById("notable-traits-data"); if (data) { - // @ts-expect-error window.NOTABLE_TRAITS = JSON.parse(data.innerText); } else { throw new Error("showTooltip() called with notable without any notable traits!"); @@ -1341,14 +1335,15 @@ function preLoadCss(cssUrl) { } // Make this function idempotent. If the tooltip is already shown, avoid doing extra work // and leave it alone. - // @ts-expect-error if (window.CURRENT_TOOLTIP_ELEMENT && window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE === e) { - // @ts-expect-error clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT); return; } window.hideAllModals(false); - const wrapper = document.createElement("div"); + // use Object.assign to make sure the object has the correct type + // with all of the correct fields before it is assigned to a variable, + // as typescript has no way to change the type of a variable once it is initialized. + const wrapper = Object.assign(document.createElement("div"), {TOOLTIP_BASE: e}); if (notable_ty) { wrapper.innerHTML = "<div class=\"content\">" + // @ts-expect-error @@ -1394,11 +1389,7 @@ function preLoadCss(cssUrl) { ); } wrapper.style.visibility = ""; - // @ts-expect-error window.CURRENT_TOOLTIP_ELEMENT = wrapper; - // @ts-expect-error - window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE = e; - // @ts-expect-error clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT); wrapper.onpointerenter = ev => { // If this is a synthetic touch event, ignore it. A click event will be along shortly. @@ -1433,19 +1424,15 @@ function preLoadCss(cssUrl) { */ function setTooltipHoverTimeout(element, show) { clearTooltipHoverTimeout(element); - // @ts-expect-error if (!show && !window.CURRENT_TOOLTIP_ELEMENT) { // To "hide" an already hidden element, just cancel its timeout. return; } - // @ts-expect-error if (show && window.CURRENT_TOOLTIP_ELEMENT) { // To "show" an already visible element, just cancel its timeout. return; } - // @ts-expect-error if (window.CURRENT_TOOLTIP_ELEMENT && - // @ts-expect-error window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE !== element) { // Don't do anything if another tooltip is already visible. return; @@ -1468,24 +1455,20 @@ function preLoadCss(cssUrl) { */ function clearTooltipHoverTimeout(element) { if (element.TOOLTIP_HOVER_TIMEOUT !== undefined) { - // @ts-expect-error removeClass(window.CURRENT_TOOLTIP_ELEMENT, "fade-out"); clearTimeout(element.TOOLTIP_HOVER_TIMEOUT); delete element.TOOLTIP_HOVER_TIMEOUT; } } - // @ts-expect-error + /** + * @param {Event & { relatedTarget: Node }} event + */ function tooltipBlurHandler(event) { - // @ts-expect-error if (window.CURRENT_TOOLTIP_ELEMENT && - // @ts-expect-error !window.CURRENT_TOOLTIP_ELEMENT.contains(document.activeElement) && - // @ts-expect-error !window.CURRENT_TOOLTIP_ELEMENT.contains(event.relatedTarget) && - // @ts-expect-error !window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(document.activeElement) && - // @ts-expect-error !window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(event.relatedTarget) ) { // Work around a difference in the focus behaviour between Firefox, Chrome, and Safari. @@ -1507,30 +1490,22 @@ function preLoadCss(cssUrl) { * If set to `false`, leave keyboard focus alone. */ function hideTooltip(focus) { - // @ts-expect-error if (window.CURRENT_TOOLTIP_ELEMENT) { - // @ts-expect-error if (window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE) { if (focus) { - // @ts-expect-error window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus(); } - // @ts-expect-error window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE = false; } - // @ts-expect-error document.body.removeChild(window.CURRENT_TOOLTIP_ELEMENT); - // @ts-expect-error clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT); - // @ts-expect-error - window.CURRENT_TOOLTIP_ELEMENT = null; + window.CURRENT_TOOLTIP_ELEMENT = undefined; } } onEachLazy(document.getElementsByClassName("tooltip"), e => { e.onclick = () => { e.TOOLTIP_FORCE_VISIBLE = e.TOOLTIP_FORCE_VISIBLE ? false : true; - // @ts-expect-error if (window.CURRENT_TOOLTIP_ELEMENT && !e.TOOLTIP_FORCE_VISIBLE) { hideTooltip(true); } else { @@ -1566,9 +1541,7 @@ function preLoadCss(cssUrl) { if (ev.pointerType !== "mouse") { return; } - // @ts-expect-error if (!e.TOOLTIP_FORCE_VISIBLE && window.CURRENT_TOOLTIP_ELEMENT && - // @ts-expect-error !window.CURRENT_TOOLTIP_ELEMENT.contains(ev.relatedTarget)) { // Tooltip pointer leave gesture: // @@ -1601,7 +1574,6 @@ function preLoadCss(cssUrl) { // * https://www.nngroup.com/articles/tooltip-guidelines/ // * https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown setTooltipHoverTimeout(e, false); - // @ts-expect-error addClass(window.CURRENT_TOOLTIP_ELEMENT, "fade-out"); } }; @@ -1707,8 +1679,7 @@ function preLoadCss(cssUrl) { if (isHelpPage) { const help_section = document.createElement("section"); help_section.appendChild(container); - // @ts-expect-error - document.getElementById("main-content").appendChild(help_section); + nonnull(document.getElementById("main-content")).appendChild(help_section); } else { onEachLazy(document.getElementsByClassName("help-menu"), menu => { if (menu.offsetWidth !== 0) { @@ -1854,8 +1825,7 @@ function preLoadCss(cssUrl) { sidebarButton.addEventListener("click", e => { removeClass(document.documentElement, "hide-sidebar"); updateLocalStorage("hide-sidebar", "false"); - if (document.querySelector(".rustdoc.src")) { - // @ts-expect-error + if (window.rustdocToggleSrcSidebar) { window.rustdocToggleSrcSidebar(); } e.preventDefault(); diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 28852125fe1..3ac10742e41 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -28,6 +28,9 @@ declare global { currentTheme: HTMLLinkElement|null; /** Generated in `render/context.rs` */ SIDEBAR_ITEMS?: { [key: string]: string[] }; + /** Notable trait data */ + NOTABLE_TRAITS?: { [key: string]: string }; + CURRENT_TOOLTIP_ELEMENT?: HTMLElement & { TOOLTIP_BASE: HTMLElement }; /** Used by the popover tooltip code. */ RUSTDOC_TOOLTIP_HOVER_MS: number; /** Used by the popover tooltip code. */ @@ -93,6 +96,10 @@ declare global { pending_type_impls?: rustdoc.TypeImpls, rustdoc_add_line_numbers_to_examples?: function(), rustdoc_remove_line_numbers_from_examples?: function(), + /** JSON-encoded raw search index */ + searchIndex: string, + /** Used in search index shards in order to load data into the in-memory database */ + rr_: function(string), } interface HTMLElement { /** Used by the popover tooltip code. */ diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 42b87d56252..3fb4db3a89c 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -587,6 +587,45 @@ function getNextElem(query, parserState, elems, isInGenerics) { /** @type {rustdoc.ParserQueryElement[]} */ const generics = []; + /** @type {function(string, string): void} */ + const handleRefOrPtr = (chr, name) => { + if (parserState.typeFilter !== null && parserState.typeFilter !== "primitive") { + throw [ + "Invalid search type: primitive ", + chr, + " and ", + parserState.typeFilter, + " both specified", + ]; + } + parserState.typeFilter = null; + parserState.pos += 1; + let c = parserState.userQuery[parserState.pos]; + while (c === " " && parserState.pos < parserState.length) { + parserState.pos += 1; + c = parserState.userQuery[parserState.pos]; + } + const generics = []; + const pos = parserState.pos; + if (parserState.userQuery.slice(pos, pos + 3) === "mut") { + generics.push(makePrimitiveElement("mut", { typeFilter: "keyword" })); + parserState.pos += 3; + c = parserState.userQuery[parserState.pos]; + } else if (chr === "*" && parserState.userQuery.slice(pos, pos + 5) === "const") { + // make *const T parse the same as *T + parserState.pos += 5; + c = parserState.userQuery[parserState.pos]; + } + while (c === " " && parserState.pos < parserState.length) { + parserState.pos += 1; + c = parserState.userQuery[parserState.pos]; + } + if (!isEndCharacter(c) && parserState.pos < parserState.length) { + getFilteredNextElem(query, parserState, generics, isInGenerics); + } + elems.push(makePrimitiveElement(name, { generics })); + }; + skipWhitespace(parserState); let start = parserState.pos; let end; @@ -636,36 +675,9 @@ function getNextElem(query, parserState, elems, isInGenerics) { elems.push(makePrimitiveElement(name, { bindingName, generics })); } } else if (parserState.userQuery[parserState.pos] === "&") { - if (parserState.typeFilter !== null && parserState.typeFilter !== "primitive") { - throw [ - "Invalid search type: primitive ", - "&", - " and ", - parserState.typeFilter, - " both specified", - ]; - } - parserState.typeFilter = null; - parserState.pos += 1; - let c = parserState.userQuery[parserState.pos]; - while (c === " " && parserState.pos < parserState.length) { - parserState.pos += 1; - c = parserState.userQuery[parserState.pos]; - } - const generics = []; - if (parserState.userQuery.slice(parserState.pos, parserState.pos + 3) === "mut") { - generics.push(makePrimitiveElement("mut", { typeFilter: "keyword" })); - parserState.pos += 3; - c = parserState.userQuery[parserState.pos]; - } - while (c === " " && parserState.pos < parserState.length) { - parserState.pos += 1; - c = parserState.userQuery[parserState.pos]; - } - if (!isEndCharacter(c) && parserState.pos < parserState.length) { - getFilteredNextElem(query, parserState, generics, isInGenerics); - } - elems.push(makePrimitiveElement("reference", { generics })); + handleRefOrPtr("&", "reference"); + } else if (parserState.userQuery[parserState.pos] === "*") { + handleRefOrPtr("*", "pointer"); } else { const isStringElem = parserState.userQuery[start] === "\""; // We handle the strings on their own mostly to make code easier to follow. @@ -1185,6 +1197,7 @@ class DocSearch { this.typeNameIdOfUnit = -1; this.typeNameIdOfTupleOrUnit = -1; this.typeNameIdOfReference = -1; + this.typeNameIdOfPointer = -1; this.typeNameIdOfHof = -1; this.utf8decoder = new TextDecoder(); @@ -1224,6 +1237,7 @@ class DocSearch { tupleOrUnit, // reference matches `&` reference, + pointer, // never matches `!` never, ] = await Promise.all([ @@ -1239,6 +1253,7 @@ class DocSearch { nn.search("unit"), nn.search("()"), nn.search("reference"), + nn.search("pointer"), nn.search("never"), ]); /** @@ -1270,6 +1285,7 @@ class DocSearch { this.typeNameIdOfUnit = await first(unit, TY_PRIMITIVE, ""); this.typeNameIdOfTupleOrUnit = await first(tupleOrUnit, TY_PRIMITIVE, ""); this.typeNameIdOfReference = await first(reference, TY_PRIMITIVE, ""); + this.typeNameIdOfPointer = await first(pointer, TY_PRIMITIVE, ""); this.typeNameIdOfHof = await first(hof, TY_PRIMITIVE, ""); this.typeNameIdOfNever = await first(never, TY_PRIMITIVE, ""); } @@ -2309,6 +2325,25 @@ class DocSearch { }, result), ); return true; + } else if (fnType.id === this.typeNameIdOfPointer) { + pushText({ name: "*", highlighted: fnType.highlighted }, result); + if (fnType.generics.length < 2) { + pushText({ name: "const ", highlighted: fnType.highlighted }, result); + } + let prevHighlighted = false; + await onEachBtwnAsync( + fnType.generics, + async value => { + prevHighlighted = !!value.highlighted; + await writeFn(value, result); + }, + // @ts-expect-error + value => pushText({ + name: " ", + highlighted: prevHighlighted && value.highlighted, + }, result), + ); + return true; } else if ( fnType.id === this.typeNameIdOfFn || fnType.id === this.typeNameIdOfFnMut || @@ -5244,9 +5279,7 @@ if (typeof window !== "undefined") { // search.index/root is loaded by main.js, so // this script doesn't need to launch it, but // must pick it up - // @ts-ignore if (window.searchIndex) { - // @ts-ignore window.rr_(window.searchIndex); } }, diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index c055eb0f808..40ab8be03c9 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -117,7 +117,7 @@ function addClass(elem, className) { * Remove a class from a DOM Element. If `elem` is null, * does nothing. This function is idempotent. * - * @param {Element|null} elem + * @param {Element|null|undefined} elem * @param {string} className */ // eslint-disable-next-line no-unused-vars  | 
