From a7cb1a5352e648bcf5ffb1403b6535275a6c511d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 29 Jul 2024 13:58:15 +0200 Subject: [PATCH 1/2] Make the buttons remain when code example is clicked --- src/librustdoc/html/static/css/rustdoc.css | 15 ++++++++++++- src/librustdoc/html/static/js/main.js | 25 ++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index e936e1ca07ecd..1b9dfdf3fdd67 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1474,7 +1474,20 @@ a.test-arrow:hover { .example-wrap:hover > .test-arrow { padding: 2px 7px; } -.example-wrap:hover > .test-arrow, .example-wrap:hover > .button-holder { +/* +On iPad, the ":hover" state sticks around, making things work not greatly. Do work around +it, we move it into this media query. More information can be found at: +https://css-tricks.com/solving-sticky-hover-states-with-media-hover-hover/ + +However, using `@media (hover: hover)` makes this rule never to be applied in GUI tests, so +instead, we check that it's not a "finger" cursor. +*/ +@media not (pointer: coarse) { + .example-wrap:hover > .test-arrow, .example-wrap:hover > .button-holder { + visibility: visible; + } +} +.example-wrap .button-holder.keep-visible { visibility: visible; } .example-wrap .button-holder .copy-button { diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 40d65ae7910e2..e0ea234f9e710 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1829,14 +1829,22 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm copyContentToClipboard(codeElem.textContent); } - function addCopyButton(event) { + function getExampleWrap(event) { let elem = event.target; while (!hasClass(elem, "example-wrap")) { elem = elem.parentElement; if (elem.tagName === "body" || hasClass(elem, "docblock")) { - return; + return null; } } + return elem; + } + + function addCopyButton(event) { + const elem = getExampleWrap(event); + if (elem === null) { + return; + } // Since the button will be added, no need to keep this listener around. elem.removeEventListener("mouseover", addCopyButton); @@ -1858,7 +1866,20 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm parent.appendChild(copyButton); } + function showHideCodeExampleButtons(event) { + const elem = getExampleWrap(event); + if (elem === null) { + return; + } + const buttons = elem.querySelector(".button-holder"); + if (buttons === null) { + return; + } + buttons.classList.toggle("keep-visible"); + } + onEachLazy(document.querySelectorAll(".docblock .example-wrap"), elem => { elem.addEventListener("mouseover", addCopyButton); + elem.addEventListener("click", showHideCodeExampleButtons); }); }()); From 99906dc89c241d29c6e63d10f719d36d81a9a049 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 29 Jul 2024 13:58:33 +0200 Subject: [PATCH 2/2] Add rustdoc GUI test to check click on code examples --- tests/rustdoc-gui/code-example-buttons.goml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/rustdoc-gui/code-example-buttons.goml diff --git a/tests/rustdoc-gui/code-example-buttons.goml b/tests/rustdoc-gui/code-example-buttons.goml new file mode 100644 index 0000000000000..57ea2970072e6 --- /dev/null +++ b/tests/rustdoc-gui/code-example-buttons.goml @@ -0,0 +1,21 @@ +// This test ensures that code blocks buttons are displayed on hover and when you click on them. +go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" + +// First we check we "hover". +move-cursor-to: ".example-wrap" +assert-css: (".example-wrap .copy-button", { "visibility": "visible" }) +move-cursor-to: ".search-input" +assert-css: (".example-wrap .copy-button", { "visibility": "hidden" }) + +// Now we check the click. +assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0) +click: ".example-wrap" +move-cursor-to: ".search-input" +// It should have a new class and be visible. +wait-for-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 1) +wait-for-css: (".example-wrap:not(:hover) .button-holder.keep-visible", { "visibility": "visible" }) +// Clicking again will remove the class. +click: ".example-wrap" +move-cursor-to: ".search-input" +assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0) +assert-css: (".example-wrap .copy-button", { "visibility": "hidden" })