diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 09d289d570c06..7f47856948493 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1987,12 +1987,10 @@ a.tooltip:hover::after { color: inherit; } #search-tabs button:not(.selected) { - --search-tab-button-background: var(--search-tab-button-not-selected-background); background-color: var(--search-tab-button-not-selected-background); border-top-color: var(--search-tab-button-not-selected-border-top-color); } #search-tabs button:hover, #search-tabs button.selected { - --search-tab-button-background: var(--search-tab-button-selected-background); background-color: var(--search-tab-button-selected-background); border-top-color: var(--search-tab-button-selected-border-top-color); } @@ -2008,66 +2006,27 @@ a.tooltip:hover::after { color: transparent; } -.search-form.loading { - --search-tab-button-background: var(--button-background-color); -} - -#search-tabs .count.loading::before, -.search-form.loading::before -{ - width: 16px; - height: 16px; - border-radius: 16px; - background: radial-gradient( - var(--search-tab-button-background) 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; - left: 2px; - top: 2px; - animation: rotating 1.25s linear infinite; -} -#search-tabs .count.loading::after, .search-form.loading::after { width: 18px; height: 18px; border-radius: 18px; - background: conic-gradient( - var(--search-tab-button-background) 0deg 180deg, - transparent 270deg 360deg - ); - content: ""; + /* hourglass */ + content: url('data:image/svg+xml,\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + '); position: absolute; - left: 1px; - top: 1px; - animation: rotating 0.66s linear infinite; -} - -.search-form.loading::before { - left: auto; - right: 9px; - top: 8px; -} - -.search-form.loading::after { - left: auto; right: 8px; top: 8px; + filter: var(--settings-menu-filter); } #search .error code { diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 9a6d4c710ff5d..0929d351463cc 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1,5 +1,5 @@ // ignore-tidy-filelength -/* global addClass, getNakedUrl, getVar, nonnull, getSettingValue */ +/* global addClass, getNakedUrl, getVar, getSettingValue, hasClass, nonnull */ /* global onEachLazy, removeClass, searchState, browserSupportsHistoryApi */ "use strict"; @@ -4804,6 +4804,15 @@ function printTab(nb) { if (nb === iter) { addClass(elem, "selected"); foundCurrentTab = true; + onEachLazy(document.querySelectorAll( + ".search-form", + ), form => { + if (hasClass(elem.firstElementChild, "loading")) { + addClass(form, "loading"); + } else { + removeClass(form, "loading"); + } + }); } else { removeClass(elem, "selected"); } @@ -5019,7 +5028,9 @@ ${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); + }); } }); }; @@ -5156,6 +5167,7 @@ function makeTab(tabNb, text, results, query, isTypeSearch, goToFirst) { count < 100 ? `\u{2007}(${count})\u{2007}` : `\u{2007}(${count})`; tabCount.innerHTML = fmtNbElems; tabCount.className = "count"; + printTab(window.searchState.currentTab); }, isTypeSearch), ]; } @@ -5215,9 +5227,12 @@ 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-results active" : "search-results"; + placeholder.innerHTML = "Loading..."; output.then(output => { if (placeholder.parentElement) { placeholder.parentElement.replaceChild(output, placeholder); @@ -5474,11 +5489,6 @@ if (ROOT_PATH === null) { const database = await Stringdex.loadDatabase(hooks); if (typeof window !== "undefined") { docSearch = new DocSearch(ROOT_PATH, database); - onEachLazy(document.querySelectorAll( - ".search-form.loading", - ), form => { - removeClass(form, "loading"); - }); registerSearchEvents(); // If there's a search term in the URL, execute the search now. if (window.searchState.getQueryStringParams().search !== undefined) { diff --git a/tests/rustdoc-gui/search-throbber.goml b/tests/rustdoc-gui/search-throbber.goml new file mode 100644 index 0000000000000..9d41f933af8c1 --- /dev/null +++ b/tests/rustdoc-gui/search-throbber.goml @@ -0,0 +1,23 @@ +// We are intentionally triggering errors for race-free throbber test +fail-on-request-error: false +fail-on-js-error: false + +// First, make sure the throbber goes away when done +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=" +wait-for: ".search-input" +wait-for-false: ".search-form.loading" +write-into: (".search-input", "test") +press-key: 'Enter' +wait-for-false: ".search-form.loading" + +// Make sure the throbber shows up if we prevent the search from +// ever finishing (this tactic is needed to make sure we don't get stuck +// with any race conditions). +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=" +block-network-request: "*/desc/*.js" +reload: +wait-for: ".search-input" +wait-for-false: ".search-form.loading" +write-into: (".search-input", "test") +press-key: 'Enter' +wait-for: ".search-form.loading"