diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 266ec2ac7ad7..75fdd6ade235 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1312,9 +1312,7 @@ pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &mut Context<'_>) -> O if has_notable_trait { cx.types_with_notable_traits.insert(ty.clone()); Some(format!( - "\ - ⓘ\ - ", + " ⓘ", ty = Escape(&format!("{:#}", ty.print(cx))), )) } else { @@ -1343,7 +1341,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) { if out.is_empty() { write!( &mut out, - "
{}{}",
impl_.for_.print(cx)
);
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 6a068a3d243d..1209187dc481 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -183,8 +183,6 @@ h4.code-header {
font-weight: 600;
margin: 0;
padding: 0;
- /* position notable traits in mobile mode within the header */
- position: relative;
}
#crate-search,
@@ -930,13 +928,14 @@ so that we can apply CSS-filters to change the arrow color in themes */
border-radius: 3px;
border: 1px solid var(--border-color);
font-size: 1rem;
+ --popover-arrow-offset: 11px;
}
/* This rule is to draw the little arrow connecting the settings menu to the gear icon. */
.popover::before {
content: '';
position: absolute;
- right: 11px;
+ right: var(--popover-arrow-offset);
border: solid var(--border-color);
border-width: 1px 1px 0 0;
display: inline-block;
@@ -953,10 +952,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
/* use larger max-width for help popover, but not for help.html */
#help.popover {
max-width: 600px;
-}
-
-#help.popover::before {
- right: 48px;
+ --popover-arrow-offset: 48px;
}
#help dt {
@@ -1275,54 +1271,34 @@ h3.variant {
border-right: 3px solid var(--target-border-color);
}
-.notable-traits-tooltip {
- display: inline-block;
- cursor: pointer;
+.notable-traits {
+ color: inherit;
+ margin-right: 15px;
+ position: relative;
}
-.notable-traits .notable-traits-tooltiptext {
- display: inline-block;
- visibility: hidden;
-}
-
-.notable-traits-tooltiptext {
- padding: 5px 3px 3px 3px;
- border-radius: 6px;
- margin-left: 5px;
- z-index: 10;
- font-size: 1rem;
- cursor: default;
+/* placeholder thunk so that the mouse can easily travel from "(i)" to popover
+ the resulting "hover tunnel" is a stepped triangle, approximating
+ https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown */
+.notable-traits:hover::after {
position: absolute;
- border: 1px solid;
+ top: calc(100% - 10px);
+ left: -15px;
+ right: -15px;
+ height: 20px;
+ content: "\00a0";
}
-.notable-traits-tooltip::after {
- /* The margin on the tooltip does not capture hover events,
- this extends the area of hover enough so that mouse hover is not
- lost when moving the mouse to the tooltip */
- content: "\00a0\00a0\00a0";
+.notable .docblock {
+ margin: 0.25em 0.5em;
}
-.notable-traits-tooltiptext .docblock {
- margin: 0;
-}
-
-.notable-traits-tooltiptext .notable {
- font-size: 1.1875rem;
- font-weight: 600;
- display: block;
-}
-
-.notable-traits-tooltiptext pre, .notable-traits-tooltiptext code {
+.notable .docblock pre, .notable .docblock code {
background: transparent;
-}
-
-.notable-traits-tooltiptext .docblock pre.content {
margin: 0;
padding: 0;
font-size: 1.25rem;
white-space: pre-wrap;
- overflow: hidden;
}
.search-failed {
@@ -1365,12 +1341,6 @@ h3.variant {
font-size: 1rem;
}
-.notable-traits {
- cursor: pointer;
- z-index: 2;
- margin-left: 5px;
-}
-
#sidebar-toggle {
position: sticky;
top: 0;
@@ -1855,11 +1825,6 @@ in storage.js
border-bottom: 1px solid;
}
- .notable-traits .notable-traits-tooltiptext {
- left: 0;
- top: 100%;
- }
-
/* We don't display the help button on mobile devices. */
#help-button {
display: none;
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 2fa1fa39d63a..eec3ce55e22f 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -183,10 +183,6 @@ details.rustdoc-toggle > summary::before {
border-color: transparent #314559 transparent transparent;
}
-.notable-traits-tooltiptext {
- background-color: #314559;
-}
-
#titles > button.selected {
background-color: #141920 !important;
border-bottom: 1px solid #ffb44c !important;
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 43f8dd42ab34..a93d9d6790a1 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -106,10 +106,6 @@ details.rustdoc-toggle > summary::before {
border-color: transparent black transparent transparent;
}
-.notable-traits-tooltiptext {
- background-color: #111;
-}
-
#titles > button:not(.selected) {
background-color: #252525;
border-top-color: #252525;
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index c8c5289ab540..e69ae5abbc39 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -98,10 +98,6 @@ body.source .example-wrap pre.rust a {
border-color: transparent black transparent transparent;
}
-.notable-traits-tooltiptext {
- background-color: #eee;
-}
-
#titles > button:not(.selected) {
background-color: #e6e6e6;
border-top-color: #e6e6e6;
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 0426774e80d4..b670ea3f0201 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -850,18 +850,33 @@ function loadCss(cssUrl) {
}
hideNotable();
const ty = e.getAttribute("data-ty");
- const tooltip = e.getElementsByClassName("notable-traits-tooltip")[0];
const wrapper = document.createElement("div");
wrapper.innerHTML = "" + window.NOTABLE_TRAITS[ty] + "";
- wrapper.className = "notable-traits-tooltiptext";
- tooltip.appendChild(wrapper);
- const pos = wrapper.getBoundingClientRect();
- tooltip.removeChild(wrapper);
- wrapper.style.top = (pos.top + window.scrollY) + "px";
- wrapper.style.left = (pos.left + window.scrollX) + "px";
- wrapper.style.width = pos.width + "px";
+ wrapper.className = "notable popover";
+ const focusCatcher = document.createElement("div");
+ focusCatcher.setAttribute("tabindex", "0");
+ focusCatcher.onfocus = hideNotable;
+ wrapper.appendChild(focusCatcher);
+ const pos = e.getBoundingClientRect();
+ // 5px overlap so that the mouse can easily travel from place to place
+ wrapper.style.top = (pos.top + window.scrollY + pos.height) + "px";
+ wrapper.style.left = 0;
+ wrapper.style.right = "auto";
+ wrapper.style.visibility = "hidden";
const body = document.getElementsByTagName("body")[0];
body.appendChild(wrapper);
+ const wrapperPos = wrapper.getBoundingClientRect();
+ // offset so that the arrow points at the center of the "(i)"
+ const finalPos = pos.left + window.scrollX - wrapperPos.width + 24;
+ if (finalPos > 0) {
+ wrapper.style.left = finalPos + "px";
+ } else {
+ wrapper.style.setProperty(
+ "--popover-arrow-offset",
+ (wrapperPos.right - pos.right + 4) + "px"
+ );
+ }
+ wrapper.style.visibility = "";
window.CURRENT_NOTABLE_ELEMENT = wrapper;
window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE = e;
wrapper.onpointerleave = function(ev) {
@@ -875,9 +890,23 @@ function loadCss(cssUrl) {
};
}
+ function notableBlurHandler(event) {
+ if (window.CURRENT_NOTABLE_ELEMENT &&
+ !elemIsInParent(document.activeElement, window.CURRENT_NOTABLE_ELEMENT) &&
+ !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT) &&
+ !elemIsInParent(document.activeElement, window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE) &&
+ !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE)
+ ) {
+ hideNotable();
+ }
+ }
+
function hideNotable() {
if (window.CURRENT_NOTABLE_ELEMENT) {
- window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false;
+ if (window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE) {
+ window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.focus();
+ window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false;
+ }
const body = document.getElementsByTagName("body")[0];
body.removeChild(window.CURRENT_NOTABLE_ELEMENT);
window.CURRENT_NOTABLE_ELEMENT = null;
@@ -891,7 +920,11 @@ function loadCss(cssUrl) {
hideNotable();
} else {
showNotable(this);
+ window.CURRENT_NOTABLE_ELEMENT.setAttribute("tabindex", "0");
+ window.CURRENT_NOTABLE_ELEMENT.focus();
+ window.CURRENT_NOTABLE_ELEMENT.onblur = notableBlurHandler;
}
+ return false;
};
e.onpointerenter = function(ev) {
// If this is a synthetic touch event, ignore it. A click event will be along shortly.
@@ -1018,6 +1051,7 @@ function loadCss(cssUrl) {
onEachLazy(document.querySelectorAll(".search-form .popover"), elem => {
elem.style.display = "none";
});
+ hideNotable();
};
/**
diff --git a/src/test/rustdoc-gui/notable-trait.goml b/src/test/rustdoc-gui/notable-trait.goml
index d8261d8dc902..3bc1c5365e9e 100644
--- a/src/test/rustdoc-gui/notable-trait.goml
+++ b/src/test/rustdoc-gui/notable-trait.goml
@@ -22,31 +22,26 @@ assert-position: (
)
assert-position: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- {"x": 951},
+ {"x": 955},
)
-// The tooltip should be beside the `i`
+// The tooltip should be below the `i`
// Also, clicking the tooltip should bring its text into the DOM
-assert-count: ("//*[@class='notable-traits-tooltiptext']", 0)
+assert-count: ("//*[@class='notable popover']", 0)
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
-assert-count: ("//*[@class='notable-traits-tooltiptext']", 1)
+assert-count: ("//*[@class='notable popover']", 1)
compare-elements-position-near: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@class='notable-traits-tooltiptext']",
- {"y": 2}
+ "//*[@class='notable popover']",
+ {"y": 30}
)
compare-elements-position-false: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@class='notable-traits-tooltiptext']",
+ "//*[@class='notable popover']",
("x")
)
-// The docblock should be flush with the border.
-assert-css: (
- "//*[@class='notable-traits-tooltiptext']/*[@class='docblock']",
- {"margin-left": "0px"}
-)
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
move-cursor-to: "//h1"
-assert-count: ("//*[@class='notable-traits-tooltiptext']", 0)
+assert-count: ("//*[@class='notable popover']", 0)
// Now only the `i` should be on the next line.
size: (1055, 600)
@@ -77,7 +72,7 @@ assert-position: (
)
assert-position: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- {"x": 519},
+ {"x": 523},
)
// Checking on mobile now.
@@ -101,34 +96,28 @@ assert-position: (
)
assert-position: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- {"x": 289},
+ {"x": 293},
)
-// The tooltip should be below `i`
+// The tooltip should STILL be below `i`
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
-assert-count: ("//*[@class='notable-traits-tooltiptext']", 1)
-compare-elements-position-near-false: (
+assert-count: ("//*[@class='notable popover']", 1)
+compare-elements-position-near: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@class='notable-traits-tooltiptext']",
- {"y": 2}
+ "//*[@class='notable popover']",
+ {"y": 30}
)
compare-elements-position-false: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@class='notable-traits-tooltiptext']",
+ "//*[@class='notable popover']",
("x")
)
-compare-elements-position-near: (
- "//*[@id='method.create_an_iterator_from_read']",
- "//*[@class='notable-traits-tooltiptext']",
- {"x": 10}
-)
-// The docblock should be flush with the border.
-assert-css: (
- "//*[@class='notable-traits-tooltiptext']/*[@class='docblock']",
- {"margin-left": "0px"}
+assert-position: (
+ "//*[@class='notable popover']",
+ {"x": 0}
)
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
move-cursor-to: "//h1"
-assert-count: ("//*[@class='notable-traits-tooltiptext']", 0)
+assert-count: ("//*[@class='notable popover']", 0)
// Checking on very small mobile. The `i` should be on its own line.
size: (365, 600)
@@ -153,25 +142,25 @@ define-function: (
("reload"),
("move-cursor-to", "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"),
- ("assert-count", (".notable-traits-tooltiptext", 1)),
+ ("assert-count", (".notable.popover", 1)),
("assert-css", (
- ".notable-traits-tooltiptext h3.notable",
+ ".notable.popover h3",
{"color": |header_color|},
ALL,
)),
("assert-css", (
- ".notable-traits-tooltiptext pre.content",
+ ".notable.popover pre",
{"color": |content_color|},
ALL,
)),
("assert-css", (
- ".notable-traits-tooltiptext pre.content a.struct",
+ ".notable.popover pre a.struct",
{"color": |type_color|},
ALL,
)),
("assert-css", (
- ".notable-traits-tooltiptext pre.content a.trait",
+ ".notable.popover pre a.trait",
{"color": |trait_color|},
ALL,
)),