From 2773d24fb701cb17d587289cf75725b5d9bcd328 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 10 Sep 2025 11:23:40 -0700 Subject: [PATCH] rustdoc-search: put throbber at bottom of search results instead --- src/librustdoc/html/static/css/rustdoc.css | 52 ++++++++++++++++++++++ src/librustdoc/html/static/js/search.js | 19 ++++++-- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index a0b3b2de3dbf..d86dc66ab01b 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -339,6 +339,7 @@ summary.hideme, .scraped-example-list, .rustdoc-breadcrumbs, .search-switcher, +.search-throbber, /* This selector is for the items listed in the "all items" page. */ ul.all-items { font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif; @@ -2006,6 +2007,57 @@ a.tooltip:hover::after { color: transparent; } +.search-throbber { + position: relative; + height: 34px; +} + +.search-throbber::before, +.search-form.loading::before +{ + width: 16px; + height: 16px; + border-radius: 16px; + background: radial-gradient( + var(--button-background-color) 0 50%, + transparent 50% 100% + ), conic-gradient( + var(--code-highlight-kw-color) 0deg 30deg, + var(--code-highlight-prelude-color) 30deg 60deg, + var(--code-highlight-number-color) 90deg 120deg, + var(--code-highlight-lifetime-color ) 120deg 150deg, + var(--code-highlight-comment-color) 150deg 180deg, + var(--code-highlight-self-color) 180deg 210deg, + var(--code-highlight-attribute-color) 210deg 240deg, + var(--code-highlight-literal-color) 210deg 240deg, + var(--code-highlight-macro-color) 240deg 270deg, + var(--code-highlight-question-mark-color) 270deg 300deg, + var(--code-highlight-prelude-val-color) 300deg 330deg, + var(--code-highlight-doc-comment-color) 330deg 360deg + ); + content: ""; + position: absolute; + right: 9px; + top: 8px; + animation: rotating 1.25s linear infinite; +} +.search-throbber::after, +.search-form.loading::after +{ + width: 18px; + height: 18px; + border-radius: 18px; + background: conic-gradient( + var(--button-background-color) 0deg 180deg, + transparent 270deg 360deg + ); + content: ""; + position: absolute; + right: 8px; + top: 8px; + animation: rotating 0.66s linear infinite; +} + #search .error code { border-radius: 3px; background-color: var(--search-error-code-background-color); diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 9a6d4c710ff5..ba8363b1a914 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -4904,6 +4904,11 @@ async function addTab(results, query, display, finishedCallback, isTypeSearch) { let output = document.createElement("ul"); output.className = "search-results " + extraClass; + const throbber = document.createElement("div"); + throbber.className = "search-throbber"; + throbber.innerHTML = "Loading..."; + output.appendChild(throbber); + let count = 0; /** @type {Promise[]} */ @@ -5010,7 +5015,7 @@ ${obj.displayPath}${name}\ } link.appendChild(description); - output.appendChild(link); + output.insertBefore(link, throbber); results.next().then(async nextResult => { if (nextResult.value) { @@ -5019,7 +5024,10 @@ ${obj.displayPath}${name}\ await Promise.all(descList); // need to make sure the element is shown before // running this callback - yieldToBrowser().then(() => finishedCallback(count, output)); + yieldToBrowser().then(() => { + finishedCallback(count, output); + throbber.remove(); + }); } }); }; @@ -5215,9 +5223,14 @@ async function showResults(docSearch, results, goToFirst, filterCrates) { resultsElem.id = "results"; search.innerHTML = ""; - for (const [tab, output] of tabs) { + for (const [tabNb, [tab, output]] of tabs.entries()) { tabsElem.appendChild(tab); + const isCurrentTab = window.searchState.currentTab === tabNb; const placeholder = document.createElement("div"); + placeholder.className = isCurrentTab ? + "search-throbber search-results active" : + "search-throbber search-results"; + placeholder.innerHTML = "Loading..."; output.then(output => { if (placeholder.parentElement) { placeholder.parentElement.replaceChild(output, placeholder);