Skip to content

Commit c2b085b

Browse files
authored
Rollup merge of rust-lang#128339 - GuillaumeGomez:click-code-example, r=notriddle
[rustdoc] Make the buttons remain when code example is clicked Follow-up of rust-lang#125779. One current issue we have with "run" button and the newly added copy code button is that if you're on mobile devices, you can't use them. I took a look at how `mdbook` is handling it and when you click on a code example, they show the buttons. I think it's a really good idea as if you want to copy the code on your mobile device, you will click on it, showing the buttons. Feature can be tested [here](https://rustdoc.crud.net/imperio/click-code-example/foo/struct.Bar.html). r? `@notriddle`
2 parents f396a42 + 99906dc commit c2b085b

File tree

3 files changed

+58
-3
lines changed

3 files changed

+58
-3
lines changed

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

+14-1
Original file line numberDiff line numberDiff line change
@@ -1477,7 +1477,20 @@ a.test-arrow:hover {
14771477
.example-wrap:hover > .test-arrow {
14781478
padding: 2px 7px;
14791479
}
1480-
.example-wrap:hover > .test-arrow, .example-wrap:hover > .button-holder {
1480+
/*
1481+
On iPad, the ":hover" state sticks around, making things work not greatly. Do work around
1482+
it, we move it into this media query. More information can be found at:
1483+
https://css-tricks.com/solving-sticky-hover-states-with-media-hover-hover/
1484+
1485+
However, using `@media (hover: hover)` makes this rule never to be applied in GUI tests, so
1486+
instead, we check that it's not a "finger" cursor.
1487+
*/
1488+
@media not (pointer: coarse) {
1489+
.example-wrap:hover > .test-arrow, .example-wrap:hover > .button-holder {
1490+
visibility: visible;
1491+
}
1492+
}
1493+
.example-wrap .button-holder.keep-visible {
14811494
visibility: visible;
14821495
}
14831496
.example-wrap .button-holder .copy-button {

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

+23-2
Original file line numberDiff line numberDiff line change
@@ -1829,14 +1829,22 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
18291829
copyContentToClipboard(codeElem.textContent);
18301830
}
18311831

1832-
function addCopyButton(event) {
1832+
function getExampleWrap(event) {
18331833
let elem = event.target;
18341834
while (!hasClass(elem, "example-wrap")) {
18351835
elem = elem.parentElement;
18361836
if (elem.tagName === "body" || hasClass(elem, "docblock")) {
1837-
return;
1837+
return null;
18381838
}
18391839
}
1840+
return elem;
1841+
}
1842+
1843+
function addCopyButton(event) {
1844+
const elem = getExampleWrap(event);
1845+
if (elem === null) {
1846+
return;
1847+
}
18401848
// Since the button will be added, no need to keep this listener around.
18411849
elem.removeEventListener("mouseover", addCopyButton);
18421850

@@ -1858,7 +1866,20 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
18581866
parent.appendChild(copyButton);
18591867
}
18601868

1869+
function showHideCodeExampleButtons(event) {
1870+
const elem = getExampleWrap(event);
1871+
if (elem === null) {
1872+
return;
1873+
}
1874+
const buttons = elem.querySelector(".button-holder");
1875+
if (buttons === null) {
1876+
return;
1877+
}
1878+
buttons.classList.toggle("keep-visible");
1879+
}
1880+
18611881
onEachLazy(document.querySelectorAll(".docblock .example-wrap"), elem => {
18621882
elem.addEventListener("mouseover", addCopyButton);
1883+
elem.addEventListener("click", showHideCodeExampleButtons);
18631884
});
18641885
}());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// This test ensures that code blocks buttons are displayed on hover and when you click on them.
2+
go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
3+
4+
// First we check we "hover".
5+
move-cursor-to: ".example-wrap"
6+
assert-css: (".example-wrap .copy-button", { "visibility": "visible" })
7+
move-cursor-to: ".search-input"
8+
assert-css: (".example-wrap .copy-button", { "visibility": "hidden" })
9+
10+
// Now we check the click.
11+
assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0)
12+
click: ".example-wrap"
13+
move-cursor-to: ".search-input"
14+
// It should have a new class and be visible.
15+
wait-for-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 1)
16+
wait-for-css: (".example-wrap:not(:hover) .button-holder.keep-visible", { "visibility": "visible" })
17+
// Clicking again will remove the class.
18+
click: ".example-wrap"
19+
move-cursor-to: ".search-input"
20+
assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0)
21+
assert-css: (".example-wrap .copy-button", { "visibility": "hidden" })

0 commit comments

Comments
 (0)