Skip to content

Commit

Permalink
Generate scraped examples buttons in JS
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Sep 7, 2024
1 parent 59d4114 commit 7a31bc1
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 38 deletions.
1 change: 0 additions & 1 deletion src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2537,7 +2537,6 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c
&cx.root_path(),
highlight::DecorationInfo(decoration_info),
sources::SourceContext::Embedded(sources::ScrapedInfo {
needs_prev_next_buttons: line_ranges.len() > 1,
needs_expansion,
offset: line_min,
name: &call_data.display_name,
Expand Down
1 change: 0 additions & 1 deletion src/librustdoc/html/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,6 @@ where

pub(crate) struct ScrapedInfo<'a> {
pub(crate) offset: usize,
pub(crate) needs_prev_next_buttons: bool,
pub(crate) name: &'a str,
pub(crate) url: &'a str,
pub(crate) title: &'a str,
Expand Down
14 changes: 8 additions & 6 deletions src/librustdoc/html/static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1855,12 +1855,8 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
// Since the button will be added, no need to keep this listener around.
elem.removeEventListener("mouseover", addCopyButton);

// If this is a scrapped example, there will already be a "button-holder" element.
let parent = elem.querySelector(".button-holder");
if (!parent) {
parent = document.createElement("div");
parent.className = "button-holder";
}
let parent = document.createElement("div");
parent.className = "button-holder";

const runButton = elem.querySelector(".test-arrow");
if (runButton !== null) {
Expand All @@ -1876,6 +1872,12 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
copyButtonAnimation(copyButton);
});
parent.appendChild(copyButton);

if (!elem.parentElement.classList.contains("scraped-example")) {
return;
}
const scrapedWrapped = elem.parentElement;
window.updateScrapedExample(scrapedWrapped, parent);
}

function showHideCodeExampleButtons(event) {
Expand Down
51 changes: 34 additions & 17 deletions src/librustdoc/html/static/js/scrape-examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,30 @@
elt.querySelector(".rust").scrollTo(0, scrollOffset);
}

function updateScrapedExample(example, isHidden) {
const locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
function createScrapeButton(parent, className, content) {
const button = document.createElement("button");
button.className = className;
button.innerText = content;
parent.insertBefore(button, parent.firstChild);
return button;
}

window.updateScrapedExample = (example, buttonHolder) => {
let locIndex = 0;
const highlights = Array.prototype.slice.call(example.querySelectorAll(".highlight"));
const link = example.querySelector(".scraped-example-title a");
let expandButton = null;

if (!example.classList.contains("expanded")) {
expandButton = createScrapeButton(buttonHolder, "expand", "↕");
}
const isHidden = example.parentElement.classList.contains("more-scraped-examples");

const locs = example.locs;
if (locs.length > 1) {
const next = createScrapeButton(buttonHolder, "next", "≻");
const prev = createScrapeButton(buttonHolder, "prev", "≺");

// Toggle through list of examples in a given file
const onChangeLoc = changeIndex => {
removeClass(highlights[locIndex], "focus");
Expand All @@ -57,22 +74,19 @@
link.innerHTML = title;
};

example.querySelector(".prev")
.addEventListener("click", () => {
onChangeLoc(() => {
locIndex = (locIndex - 1 + locs.length) % locs.length;
});
prev.addEventListener("click", () => {
onChangeLoc(() => {
locIndex = (locIndex - 1 + locs.length) % locs.length;
});
});

example.querySelector(".next")
.addEventListener("click", () => {
onChangeLoc(() => {
locIndex = (locIndex + 1) % locs.length;
});
next.addEventListener("click", () => {
onChangeLoc(() => {
locIndex = (locIndex + 1) % locs.length;
});
});
}

const expandButton = example.querySelector(".expand");
if (expandButton) {
expandButton.addEventListener("click", () => {
if (hasClass(example, "expanded")) {
Expand All @@ -83,13 +97,16 @@
}
});
}
};

function setupLoc(example, isHidden) {
example.locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
// Start with the first example in view
scrollToLoc(example, locs[0][0], isHidden);
scrollToLoc(example, example.locs[0][0], isHidden);
}

const firstExamples = document.querySelectorAll(".scraped-example-list > .scraped-example");
onEachLazy(firstExamples, el => updateScrapedExample(el, false));
onEachLazy(firstExamples, el => setupLoc(el, false));
onEachLazy(document.querySelectorAll(".more-examples-toggle"), toggle => {
// Allow users to click the left border of the <details> section to close it,
// since the section can be large and finding the [+] button is annoying.
Expand All @@ -102,11 +119,11 @@
const moreExamples = toggle.querySelectorAll(".scraped-example");
toggle.querySelector("summary").addEventListener("click", () => {
// Wrapping in setTimeout ensures the update happens after the elements are actually
// visible. This is necessary since updateScrapedExample calls scrollToLoc which
// visible. This is necessary since setupLoc calls scrollToLoc which
// depends on offsetHeight, a property that requires an element to be visible to
// compute correctly.
setTimeout(() => {
onEachLazy(moreExamples, el => updateScrapedExample(el, true));
onEachLazy(moreExamples, el => setupLoc(el, true));
});
}, {once: true});
});
Expand Down
15 changes: 2 additions & 13 deletions src/librustdoc/html/templates/scraped_source.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div class="scraped-example{% if !info.needs_expansion +%} expanded{% endif %}" data-locs="{{info.locations}}"> {# #}
<div class="scraped-example-title">
{{info.name +}} (<a href="{{info.url}}">{{info.title}}</a>) {# #}
</div>
<div class="example-wrap"> {# #}
</div> {# #}
<div class="example-wrap">
{# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr
Do not show "1 2 3 4 5 ..." in web search results. #}
<div class="src-line-numbers" data-nosnippet> {# #}
Expand All @@ -18,16 +18,5 @@
{{code_html|safe}}
</code> {# #}
</pre> {# #}
{% if info.needs_prev_next_buttons || info.needs_expansion %}
<div class="button-holder">
{% if info.needs_prev_next_buttons %}
<button class="prev">&pr;</button> {# #}
<button class="next">&sc;</button>
{% endif %}
{% if info.needs_expansion %}
<button class="expand">&varr;</button>
{% endif %}
</div>
{% endif %}
</div> {# #}
</div> {# #}

0 comments on commit 7a31bc1

Please sign in to comment.