Skip to content

Commit 888ee4d

Browse files
committed
Fix tooltip link nesting glitches
1 parent 4346be5 commit 888ee4d

File tree

3 files changed

+53
-29
lines changed

3 files changed

+53
-29
lines changed

src/librustdoc/html/static/css/rustdoc.css

+11-7
Original file line numberDiff line numberDiff line change
@@ -1006,30 +1006,34 @@ so that we can apply CSS-filters to change the arrow color in themes */
10061006

10071007
.search-results {
10081008
display: none;
1009+
margin: 0;
1010+
padding: 0;
10091011
}
10101012

10111013
.search-results.active {
10121014
display: block;
10131015
}
10141016

1015-
.search-results > a {
1017+
.search-results > li {
10161018
display: flex;
1019+
cursor: pointer;
10171020
/* A little margin ensures the browser's outlining of focused links has room to display. */
1018-
margin-left: 2px;
1019-
margin-right: 2px;
1021+
margin: 0 2px;
10201022
border-bottom: 1px solid var(--search-result-border-color);
10211023
gap: 1em;
10221024
}
10231025

1024-
.search-results > a > div.desc {
1026+
.search-results > li > div.desc {
10251027
white-space: nowrap;
10261028
text-overflow: ellipsis;
10271029
overflow: hidden;
10281030
flex: 2;
10291031
}
10301032

1031-
.search-results a:hover,
1032-
.search-results a:focus {
1033+
.search-results li > a:focus,
1034+
.search-results li > a:hover,
1035+
.search-results li:hover > a,
1036+
.search-results li:focus > a {
10331037
background-color: var(--search-result-link-focus-background-color);
10341038
}
10351039

@@ -2033,7 +2037,7 @@ in src-script.js and main.js
20332037

20342038
/* Display an alternating layout on tablets and phones */
20352039
.item-table, .item-row, .item-table > li, .item-table > li > div,
2036-
.search-results > a, .search-results > a > div {
2040+
.search-results > li, .search-results > li > div {
20372041
display: block;
20382042
}
20392043

src/librustdoc/html/static/js/main.js

+17-5
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,9 @@ function preLoadCss(cssUrl) {
12651265
}
12661266

12671267
window.rustdocConfigureTooltip = e => {
1268-
e.onclick = () => {
1268+
e.addEventListener("click", ev => {
1269+
ev.preventDefault();
1270+
ev.stopPropagation();
12691271
e.TOOLTIP_FORCE_VISIBLE = e.TOOLTIP_FORCE_VISIBLE ? false : true;
12701272
if (window.CURRENT_TOOLTIP_ELEMENT && !e.TOOLTIP_FORCE_VISIBLE) {
12711273
hideTooltip(true);
@@ -1276,12 +1278,16 @@ function preLoadCss(cssUrl) {
12761278
window.CURRENT_TOOLTIP_ELEMENT.onblur = tooltipBlurHandler;
12771279
}
12781280
return false;
1279-
};
1281+
});
12801282
e.onpointerenter = ev => {
12811283
// If this is a synthetic touch event, ignore it. A click event will be along shortly.
12821284
if (ev.pointerType !== "mouse") {
12831285
return;
12841286
}
1287+
if (window.CURRENT_TOOLTIP_ELEMENT &&
1288+
window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE) {
1289+
return;
1290+
}
12851291
setTooltipHoverTimeout(e, true);
12861292
};
12871293
e.onpointermove = ev => {
@@ -1296,8 +1302,11 @@ function preLoadCss(cssUrl) {
12961302
if (ev.pointerType !== "mouse") {
12971303
return;
12981304
}
1299-
if (!e.TOOLTIP_FORCE_VISIBLE && window.CURRENT_TOOLTIP_ELEMENT &&
1300-
!window.CURRENT_TOOLTIP_ELEMENT.contains(ev.relatedTarget)) {
1305+
if (window.CURRENT_TOOLTIP_ELEMENT &&
1306+
window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE !== e) {
1307+
return;
1308+
}
1309+
if (!e.TOOLTIP_FORCE_VISIBLE) {
13011310
// Tooltip pointer leave gesture:
13021311
//
13031312
// Designing a good hover microinteraction is a matter of guessing user
@@ -1329,7 +1338,10 @@ function preLoadCss(cssUrl) {
13291338
// * https://www.nngroup.com/articles/tooltip-guidelines/
13301339
// * https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown
13311340
setTooltipHoverTimeout(e, false);
1332-
addClass(window.CURRENT_TOOLTIP_ELEMENT, "fade-out");
1341+
if (window.CURRENT_TOOLTIP_ELEMENT &&
1342+
!window.CURRENT_TOOLTIP_ELEMENT.contains(ev.relatedTarget)) {
1343+
addClass(window.CURRENT_TOOLTIP_ELEMENT, "fade-out");
1344+
}
13331345
}
13341346
};
13351347
};

src/librustdoc/html/static/js/search.js

+25-17
Original file line numberDiff line numberDiff line change
@@ -3009,27 +3009,28 @@ function initSearch(rawSearchIndex) {
30093009
async function addTab(array, query, display) {
30103010
const extraClass = display ? " active" : "";
30113011

3012-
const output = document.createElement("div");
3012+
let output;
30133013
if (array.length > 0) {
3014+
output = document.createElement("ul");
30143015
output.className = "search-results " + extraClass;
30153016

3016-
const links = Promise.all(array.map(async item => {
3017+
const lis = Promise.all(array.map(async item => {
30173018
const name = item.name;
30183019
const type = itemTypes[item.ty];
30193020
const longType = longItemTypes[item.ty];
30203021
const typeName = longType.length !== 0 ? `${longType}` : "?";
30213022

3022-
const link = document.createElement("a");
3023-
link.className = "result-" + type;
3024-
link.href = item.href;
3023+
const li = document.createElement("li");
3024+
li.className = "result-" + type;
30253025

3026-
const resultName = document.createElement("div");
3026+
const resultName = document.createElement("a");
30273027
resultName.className = "result-name";
3028+
resultName.href = item.href;
30283029

30293030
resultName.insertAdjacentHTML(
30303031
"beforeend",
30313032
`<span class="typename">${typeName}</span>`);
3032-
link.appendChild(resultName);
3033+
li.appendChild(resultName);
30333034

30343035
let alias = " ";
30353036
if (item.is_alias) {
@@ -3050,8 +3051,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\
30503051
const displayType = document.createElement("div");
30513052
if (mappedNames.size > 0 || whereClause.size > 0) {
30523053
const tooltip = document.createElement("a");
3053-
tooltip.tabIndex = -1;
30543054
tooltip.id = `tooltip-${item.id}`;
3055+
tooltip.href = `#${tooltip.id}`;
30553056
const tooltipCode = document.createElement("code");
30563057
for (const [name, qname] of mappedNames) {
30573058
const line = document.createElement("div");
@@ -3106,15 +3107,22 @@ ${item.displayPath}<span class="${type}">${name}</span>\
31063107
}
31073108
description.insertAdjacentHTML("beforeend", item.desc);
31083109

3109-
link.appendChild(description);
3110-
return link;
3110+
li.appendChild(description);
3111+
li.tabIndex = -1;
3112+
li.onclick = () => {
3113+
// allow clicking anywhere on the list item to go to the page
3114+
// even though the link itself is only the name
3115+
resultName.click();
3116+
};
3117+
return li;
31113118
}));
3112-
links.then(links => {
3113-
for (const link of links) {
3114-
output.appendChild(link);
3119+
lis.then(lis => {
3120+
for (const li of lis) {
3121+
output.appendChild(li);
31153122
}
31163123
});
31173124
} else if (query.error === null) {
3125+
output = document.createElement("div");
31183126
output.className = "search-failed" + extraClass;
31193127
output.innerHTML = "No results :(<br/>" +
31203128
"Try on <a href=\"https://duckduckgo.com/?q=" +
@@ -4176,17 +4184,17 @@ ${item.displayPath}<span class="${type}">${name}</span>\
41764184
// up and down arrow select next/previous search result, or the
41774185
// search box if we're already at the top.
41784186
if (e.which === 38) { // up
4179-
const previous = document.activeElement.previousElementSibling;
4187+
const previous = document.activeElement.parentNode.previousElementSibling;
41804188
if (previous) {
4181-
previous.focus();
4189+
previous.querySelectorAll("a").item(0).focus();
41824190
} else {
41834191
searchState.focus();
41844192
}
41854193
e.preventDefault();
41864194
} else if (e.which === 40) { // down
4187-
const next = document.activeElement.nextElementSibling;
4195+
const next = document.activeElement.parentNode.nextElementSibling;
41884196
if (next) {
4189-
next.focus();
4197+
next.querySelectorAll("a").item(0).focus();
41904198
}
41914199
const rect = document.activeElement.getBoundingClientRect();
41924200
if (window.innerHeight - rect.bottom < rect.height) {

0 commit comments

Comments
 (0)