Skip to content

Commit

Permalink
rustdoc-search: reformat type signature display
Browse files Browse the repository at this point in the history
  • Loading branch information
notriddle committed Jul 25, 2024
1 parent 2f72321 commit f8b3e1a
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 133 deletions.
51 changes: 27 additions & 24 deletions src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -1058,42 +1058,43 @@ so that we can apply CSS-filters to change the arrow color in themes */

.search-results {
display: none;
margin: 0;
padding: 0;
}

.search-results.active {
display: block;
margin: 0;
padding: 0;
}

.search-results > li {
display: flex;
cursor: pointer;
.search-results > a {
display: grid;
grid-template-areas:
"search-result-name search-result-desc"
"search-result-type-signature search-result-type-signature";
grid-template-columns: .6fr .4fr;
/* A little margin ensures the browser's outlining of focused links has room to display. */
margin: 0 2px;
border-bottom: 1px solid var(--search-result-border-color);
gap: 1em;
column-gap: 1em;
}

.search-results > li > div.desc {
.search-results > a > div.desc {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
flex: 2;
grid-area: search-result-desc;
}

.search-results li > a:focus,
.search-results li > a:hover,
.search-results li:hover > a,
.search-results li:focus > a {
.search-results a:focus,
.search-results a:hover {
background-color: var(--search-result-link-focus-background-color);
}

.search-results .result-name {
display: flex;
align-items: center;
justify-content: start;
flex: 3;
grid-area: search-result-name;
}
.search-results .result-name .alias {
color: var(--search-results-alias-color);
Expand All @@ -1115,6 +1116,11 @@ so that we can apply CSS-filters to change the arrow color in themes */
display: inline;
}

.search-results .type-signature {
grid-area: search-result-type-signature;
white-space: pre-wrap;
}

.popover {
position: absolute;
top: 100%;
Expand Down Expand Up @@ -1495,8 +1501,7 @@ a.test-arrow:hover {
position: relative;
}

.code-header a.tooltip:hover,
.search-results a.tooltip:hover {
.code-header a.tooltip:hover {
color: var(--link-color);
}

Expand Down Expand Up @@ -2118,15 +2123,15 @@ in src-script.js and main.js

/* Display an alternating layout on tablets and phones */
.item-table, .item-row, .item-table > li, .item-table > li > div,
.search-results > li, .search-results > li > div {
.search-results > a, .search-results > a > div {
display: block;
}

/* Display an alternating layout on tablets and phones */
.search-results > li {
.search-results > a {
padding: 5px 0px;
}
.search-results > li > div.desc, .item-table > li > div.desc {
.search-results > a > div.desc, .item-table > li > div.desc {
padding-left: 2em;
}
.search-results .result-name {
Expand Down Expand Up @@ -2807,19 +2812,17 @@ Original by Dempfi (https://github.com/dempfi/ayu)
border-right: 1px solid #ffb44c;
}

:root[data-theme="ayu"] .search-results li:hover > a,
:root[data-theme="ayu"] .search-results li:focus > a,
:root[data-theme="ayu"] .search-results li > a:hover,
:root[data-theme="ayu"] .search-results li > a:focus {
:root[data-theme="ayu"] .search-results a:hover,
:root[data-theme="ayu"] .search-results a:focus {
color: #fff !important;
background-color: #3c3c3c;
}

:root[data-theme="ayu"] .search-results li > a {
:root[data-theme="ayu"] .search-results a {
color: #0096cf;
}

:root[data-theme="ayu"] .search-results li div.desc {
:root[data-theme="ayu"] .search-results a div.desc {
color: #c5c5c5;
}

Expand Down
89 changes: 33 additions & 56 deletions src/librustdoc/html/static/js/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -3097,12 +3097,12 @@ function initSearch(rawSearchIndex) {
const longType = longItemTypes[item.ty];
const typeName = longType.length !== 0 ? `${longType}` : "?";

const li = document.createElement("li");
const li = document.createElement("a");
li.className = "result-" + type;
li.href = item.href;

const resultName = document.createElement("a");
const resultName = document.createElement("span");
resultName.className = "result-name";
resultName.href = item.href;

resultName.insertAdjacentHTML(
"beforeend",
Expand All @@ -3126,29 +3126,46 @@ ${item.displayPath}<span class="${type}">${name}</span>\
if (item.displayTypeSignature) {
const {type, mappedNames, whereClause} = await item.displayTypeSignature;
const displayType = document.createElement("div");
type.forEach((value, index) => {
if (index % 2 !== 0) {
const highlight = document.createElement("strong");
highlight.appendChild(document.createTextNode(value));
displayType.appendChild(highlight);
} else {
displayType.appendChild(document.createTextNode(value));
}
});
if (mappedNames.size > 0 || whereClause.size > 0) {
const tooltip = document.createElement("a");
tooltip.id = `tooltip-${item.id}`;
tooltip.href = `#${tooltip.id}`;
const tooltipCode = document.createElement("code");
let addWhereLineFn = () => {
const line = document.createElement("div");
line.className = "where";
line.appendChild(document.createTextNode("where"));
displayType.appendChild(line);
addWhereLineFn = () => {};
};
for (const [name, qname] of mappedNames) {
// don't care unless the generic name is different
if (name === qname) {
continue;
}
addWhereLineFn();
const line = document.createElement("div");
line.className = "where";
line.appendChild(document.createTextNode(`${name} is ${qname}`));
tooltipCode.appendChild(line);
line.appendChild(document.createTextNode(` ${qname} matches `));
const lineStrong = document.createElement("strong");
lineStrong.appendChild(document.createTextNode(name));
line.appendChild(lineStrong);
displayType.appendChild(line);
}
for (const [name, innerType] of whereClause) {
// don't care unless there's at least one highlighted entry
if (innerType.length <= 1) {
continue;
}
addWhereLineFn();
const line = document.createElement("div");
line.className = "where";
line.appendChild(document.createTextNode(`${name}: `));
line.appendChild(document.createTextNode(` ${name}: `));
innerType.forEach((value, index) => {
if (index % 2 !== 0) {
const highlight = document.createElement("strong");
Expand All @@ -3158,55 +3175,15 @@ ${item.displayPath}<span class="${type}">${name}</span>\
line.appendChild(document.createTextNode(value));
}
});
tooltipCode.appendChild(line);
}
if (tooltipCode.childNodes.length !== 0) {
tooltip.RUSTDOC_TOOLTIP_DOM = document.createElement("div");
tooltip.RUSTDOC_TOOLTIP_DOM.className = "content";
const tooltipH3 = document.createElement("h3");
tooltipH3.innerHTML = "About this result";
tooltip.RUSTDOC_TOOLTIP_DOM.appendChild(tooltipH3);
const tooltipPre = document.createElement("pre");
tooltipPre.appendChild(tooltipCode);
tooltip.RUSTDOC_TOOLTIP_DOM.appendChild(tooltipPre);
tooltip.typeWhereClause = whereClause;
tooltip.innerText = "ⓘ";
tooltip.className = "tooltip";
window.rustdocConfigureTooltip(tooltip);
displayType.appendChild(tooltip);
displayType.appendChild(document.createTextNode(" "));
displayType.appendChild(line);
}
}
type.forEach((value, index) => {
if (index % 2 !== 0) {
const highlight = document.createElement("strong");
highlight.appendChild(document.createTextNode(value));
displayType.appendChild(highlight);
} else {
displayType.appendChild(document.createTextNode(value));
}
});
displayType.className = "type-signature";
description.appendChild(displayType);
li.appendChild(displayType);
}
description.insertAdjacentHTML("beforeend", item.desc);

li.appendChild(description);
li.tabIndex = -1;
li.onclick = () => {
// allow user to select the description text without navigating
// also, they can select the path itself by starting the selection here
// (a UI feature I got used to from DuckDuckGo)
if (window.getSelection) {
const selection = window.getSelection();
if (selection && !selection.isCollapsed) {
return;
}
}
// allow clicking anywhere on the list item to go to the page
// even though the link itself is only the name
resultName.click();
};
return li;
}));
lis.then(lis => {
Expand Down Expand Up @@ -4293,17 +4270,17 @@ ${item.displayPath}<span class="${type}">${name}</span>\
// up and down arrow select next/previous search result, or the
// search box if we're already at the top.
if (e.which === 38) { // up
const previous = document.activeElement.parentNode.previousElementSibling;
const previous = document.activeElement.previousElementSibling;
if (previous) {
previous.querySelectorAll("a").item(0).focus();
previous.focus();
} else {
searchState.focus();
}
e.preventDefault();
} else if (e.which === 40) { // down
const next = document.activeElement.parentNode.nextElementSibling;
const next = document.activeElement.nextElementSibling;
if (next) {
next.querySelectorAll("a").item(0).focus();
next.focus();
}
const rect = document.activeElement.getBoundingClientRect();
if (window.innerHeight - rect.bottom < rect.height) {
Expand Down
33 changes: 11 additions & 22 deletions tests/rustdoc-gui/search-about-this-result.goml
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,21 @@ press-key: "Enter"

wait-for: "#search-tabs"
assert-count: ("#search-tabs button", 1)
assert-count: (".search-results > li", 1)
assert-count: (".tooltip:not(.popover)", 1)
assert-count: (".tooltip.popover", 0)
assert-count: (".search-results > a", 1)

assert: "//div[@class='type-signature']/strong[text()='Iterator']"
assert: "//div[@class='type-signature']/strong[text()='(']"
assert: "//div[@class='type-signature']/strong[text()=')']"

click: ".tooltip:not(.popover)"
wait-for: ".tooltip.popover"
assert-count: (".tooltip.popover", 1)
assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='FnMut']"
assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='Iterator::Item']"
assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='bool']"
assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='Extend']"

assert: "//div[@class='tooltip popover']//strong[text()='FnMut']"
assert: "//div[@class='tooltip popover']//strong[text()='Iterator::Item']"
assert: "//div[@class='tooltip popover']//strong[text()='bool']"
assert: "//div[@class='tooltip popover']//strong[text()='Extend']"

assert-text: (".tooltip.popover h3", "About this result")
assert-text: (".tooltip.popover pre code div:nth-child(1)", "Iterator::Item is T")
assert-text: (".tooltip.popover pre code div:nth-child(2)", "F: FnMut (&Iterator::Item) -> bool")
assert-text: (".tooltip.popover pre code div:nth-child(3)", "B: Default + Extend<Iterator::Item>")

click: ".tooltip:not(.popover)"
wait-for: 100 // wait-for-false does not exist
assert-count: (".tooltip.popover", 0)
assert-text: ("div.type-signature div.where:nth-child(4)", "where")
assert-text: ("div.type-signature div.where:nth-child(5)", " T matches Iterator::Item")
assert-text: ("div.type-signature div.where:nth-child(6)", " F: FnMut (&Iterator::Item) -> bool")
assert-text: ("div.type-signature div.where:nth-child(7)", " B: Default + Extend<Iterator::Item>")

// Try a simple result that *won't* give an info box.
go-to: "file://" + |DOC_PATH| + "/lib2/index.html?search=F->lib2::WhereWhitespace<T>"
Expand All @@ -44,9 +34,8 @@ press-key: "Enter"
wait-for: "#search-tabs"
assert-text: ("//div[@class='type-signature']", "F -> WhereWhitespace<T>")
assert-count: ("#search-tabs button", 1)
assert-count: (".search-results > li", 1)
assert-count: (".tooltip:not(.popover)", 0)
assert-count: (".tooltip.popover", 0)
assert-count: (".search-results > a", 1)
assert-count: ("//div[@class='type-signature']/div[@class='where']", 0)

assert: "//div[@class='type-signature']/strong[text()='F']"
assert: "//div[@class='type-signature']/strong[text()='WhereWhitespace']"
Expand Down
12 changes: 6 additions & 6 deletions tests/rustdoc-gui/search-keyboard.goml
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ wait-for: "#search-tabs"
press-key: "ArrowDown"
press-key: "ArrowDown"
press-key: "ArrowDown"
assert: ".search-results.active > li:nth-of-type(3) > a:focus"
assert: ".search-results.active > a:nth-of-type(3):focus"

// Now switch to the second tab, then back to the first one, then arrow back up.
press-key: "ArrowRight"
assert: ".search-results.active:nth-of-type(2) > li:nth-of-type(1) > a:focus"
assert: ".search-results.active:nth-of-type(2) > a:nth-of-type(1):focus"
press-key: "ArrowLeft"
assert: ".search-results.active:nth-of-type(1) > li:nth-of-type(3) > a:focus"
assert: ".search-results.active:nth-of-type(1) > a:nth-of-type(3):focus"
press-key: "ArrowUp"
assert: ".search-results.active > li:nth-of-type(2) > a:focus"
assert: ".search-results.active > a:nth-of-type(2):focus"
press-key: "ArrowUp"
assert: ".search-results.active > li:nth-of-type(1) > a:focus"
assert: ".search-results.active > a:nth-of-type(1):focus"
press-key: "ArrowUp"
assert: ".search-input:focus"
press-key: "ArrowDown"
assert: ".search-results.active > li:nth-of-type(1) > a:focus"
assert: ".search-results.active > a:nth-of-type(1):focus"
14 changes: 7 additions & 7 deletions tests/rustdoc-gui/search-reexport.goml
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@ assert-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgba(0,
write-into: (".search-input", "TheStdReexport")
// To be SURE that the search will be run.
press-key: 'Enter'
wait-for: "//li[@class='result-import']"
wait-for: "//a[@class='result-import']"
assert-attribute: (
"//li[@class='result-import']/a",
"//a[@class='result-import']",
{"href": "../test_docs/index.html#reexport.TheStdReexport"},
)
assert-text: ("li.result-import .result-name", "re-export test_docs::TheStdReexport")
click: "//li[@class='result-import']"
assert-text: ("a.result-import .result-name", "re-export test_docs::TheStdReexport")
click: "//a[@class='result-import']"
// We check that it has the background modified thanks to the focus.
wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "#494a3d"})

// We now check that the alias is working as well on the reexport.
// To be SURE that the search will be run.
press-key: 'Enter'
write-into: (".search-input", "AliasForTheStdReexport")
wait-for: "//li[@class='result-import']"
wait-for: "//a[@class='result-import']"
assert-text: (
"li.result-import .result-name",
"a.result-import .result-name",
"re-export AliasForTheStdReexport - see test_docs::TheStdReexport",
)
// Same thing again, we click on it to ensure the background is once again set as expected.
click: "//li[@class='result-import']"
click: "//a[@class='result-import']"
wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "#494a3d"})
Loading

0 comments on commit f8b3e1a

Please sign in to comment.