Generate scraped examples buttons in JS
This commit is contained in:
parent
59d4114b2d
commit
1ca3e90db9
5 changed files with 44 additions and 38 deletions
|
@ -2537,7 +2537,6 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c
|
||||||
&cx.root_path(),
|
&cx.root_path(),
|
||||||
highlight::DecorationInfo(decoration_info),
|
highlight::DecorationInfo(decoration_info),
|
||||||
sources::SourceContext::Embedded(sources::ScrapedInfo {
|
sources::SourceContext::Embedded(sources::ScrapedInfo {
|
||||||
needs_prev_next_buttons: line_ranges.len() > 1,
|
|
||||||
needs_expansion,
|
needs_expansion,
|
||||||
offset: line_min,
|
offset: line_min,
|
||||||
name: &call_data.display_name,
|
name: &call_data.display_name,
|
||||||
|
|
|
@ -292,7 +292,6 @@ where
|
||||||
|
|
||||||
pub(crate) struct ScrapedInfo<'a> {
|
pub(crate) struct ScrapedInfo<'a> {
|
||||||
pub(crate) offset: usize,
|
pub(crate) offset: usize,
|
||||||
pub(crate) needs_prev_next_buttons: bool,
|
|
||||||
pub(crate) name: &'a str,
|
pub(crate) name: &'a str,
|
||||||
pub(crate) url: &'a str,
|
pub(crate) url: &'a str,
|
||||||
pub(crate) title: &'a str,
|
pub(crate) title: &'a str,
|
||||||
|
|
|
@ -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.
|
// Since the button will be added, no need to keep this listener around.
|
||||||
elem.removeEventListener("mouseover", addCopyButton);
|
elem.removeEventListener("mouseover", addCopyButton);
|
||||||
|
|
||||||
// If this is a scrapped example, there will already be a "button-holder" element.
|
const parent = document.createElement("div");
|
||||||
let parent = elem.querySelector(".button-holder");
|
parent.className = "button-holder";
|
||||||
if (!parent) {
|
|
||||||
parent = document.createElement("div");
|
|
||||||
parent.className = "button-holder";
|
|
||||||
}
|
|
||||||
|
|
||||||
const runButton = elem.querySelector(".test-arrow");
|
const runButton = elem.querySelector(".test-arrow");
|
||||||
if (runButton !== null) {
|
if (runButton !== null) {
|
||||||
|
@ -1876,6 +1872,12 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
|
||||||
copyButtonAnimation(copyButton);
|
copyButtonAnimation(copyButton);
|
||||||
});
|
});
|
||||||
parent.appendChild(copyButton);
|
parent.appendChild(copyButton);
|
||||||
|
|
||||||
|
if (!elem.parentElement.classList.contains("scraped-example")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const scrapedWrapped = elem.parentElement;
|
||||||
|
window.updateScrapedExample(scrapedWrapped, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showHideCodeExampleButtons(event) {
|
function showHideCodeExampleButtons(event) {
|
||||||
|
|
|
@ -36,13 +36,30 @@
|
||||||
elt.querySelector(".rust").scrollTo(0, scrollOffset);
|
elt.querySelector(".rust").scrollTo(0, scrollOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateScrapedExample(example, isHidden) {
|
function createScrapeButton(parent, className, content) {
|
||||||
const locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
|
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;
|
let locIndex = 0;
|
||||||
const highlights = Array.prototype.slice.call(example.querySelectorAll(".highlight"));
|
const highlights = Array.prototype.slice.call(example.querySelectorAll(".highlight"));
|
||||||
const link = example.querySelector(".scraped-example-title a");
|
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) {
|
if (locs.length > 1) {
|
||||||
|
const next = createScrapeButton(buttonHolder, "next", "≻");
|
||||||
|
const prev = createScrapeButton(buttonHolder, "prev", "≺");
|
||||||
|
|
||||||
// Toggle through list of examples in a given file
|
// Toggle through list of examples in a given file
|
||||||
const onChangeLoc = changeIndex => {
|
const onChangeLoc = changeIndex => {
|
||||||
removeClass(highlights[locIndex], "focus");
|
removeClass(highlights[locIndex], "focus");
|
||||||
|
@ -57,22 +74,19 @@
|
||||||
link.innerHTML = title;
|
link.innerHTML = title;
|
||||||
};
|
};
|
||||||
|
|
||||||
example.querySelector(".prev")
|
prev.addEventListener("click", () => {
|
||||||
.addEventListener("click", () => {
|
onChangeLoc(() => {
|
||||||
onChangeLoc(() => {
|
locIndex = (locIndex - 1 + locs.length) % locs.length;
|
||||||
locIndex = (locIndex - 1 + locs.length) % locs.length;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
example.querySelector(".next")
|
next.addEventListener("click", () => {
|
||||||
.addEventListener("click", () => {
|
onChangeLoc(() => {
|
||||||
onChangeLoc(() => {
|
locIndex = (locIndex + 1) % locs.length;
|
||||||
locIndex = (locIndex + 1) % locs.length;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const expandButton = example.querySelector(".expand");
|
|
||||||
if (expandButton) {
|
if (expandButton) {
|
||||||
expandButton.addEventListener("click", () => {
|
expandButton.addEventListener("click", () => {
|
||||||
if (hasClass(example, "expanded")) {
|
if (hasClass(example, "expanded")) {
|
||||||
|
@ -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
|
// 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");
|
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 => {
|
onEachLazy(document.querySelectorAll(".more-examples-toggle"), toggle => {
|
||||||
// Allow users to click the left border of the <details> section to close it,
|
// 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.
|
// since the section can be large and finding the [+] button is annoying.
|
||||||
|
@ -102,11 +119,11 @@
|
||||||
const moreExamples = toggle.querySelectorAll(".scraped-example");
|
const moreExamples = toggle.querySelectorAll(".scraped-example");
|
||||||
toggle.querySelector("summary").addEventListener("click", () => {
|
toggle.querySelector("summary").addEventListener("click", () => {
|
||||||
// Wrapping in setTimeout ensures the update happens after the elements are actually
|
// 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
|
// depends on offsetHeight, a property that requires an element to be visible to
|
||||||
// compute correctly.
|
// compute correctly.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
onEachLazy(moreExamples, el => updateScrapedExample(el, true));
|
onEachLazy(moreExamples, el => setupLoc(el, true));
|
||||||
});
|
});
|
||||||
}, {once: true});
|
}, {once: true});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<div class="scraped-example{% if !info.needs_expansion +%} expanded{% endif %}" data-locs="{{info.locations}}"> {# #}
|
<div class="scraped-example{% if !info.needs_expansion +%} expanded{% endif %}" data-locs="{{info.locations}}"> {# #}
|
||||||
<div class="scraped-example-title">
|
<div class="scraped-example-title">
|
||||||
{{info.name +}} (<a href="{{info.url}}">{{info.title}}</a>) {# #}
|
{{info.name +}} (<a href="{{info.url}}">{{info.title}}</a>) {# #}
|
||||||
</div>
|
</div> {# #}
|
||||||
<div class="example-wrap"> {# #}
|
<div class="example-wrap">
|
||||||
{# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr
|
{# 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. #}
|
Do not show "1 2 3 4 5 ..." in web search results. #}
|
||||||
<div class="src-line-numbers" data-nosnippet> {# #}
|
<div class="src-line-numbers" data-nosnippet> {# #}
|
||||||
|
@ -18,16 +18,5 @@
|
||||||
{{code_html|safe}}
|
{{code_html|safe}}
|
||||||
</code> {# #}
|
</code> {# #}
|
||||||
</pre> {# #}
|
</pre> {# #}
|
||||||
{% if info.needs_prev_next_buttons || info.needs_expansion %}
|
|
||||||
<div class="button-holder">
|
|
||||||
{% if info.needs_prev_next_buttons %}
|
|
||||||
<button class="prev">≺</button> {# #}
|
|
||||||
<button class="next">≻</button>
|
|
||||||
{% endif %}
|
|
||||||
{% if info.needs_expansion %}
|
|
||||||
<button class="expand">↕</button>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div> {# #}
|
</div> {# #}
|
||||||
</div> {# #}
|
</div> {# #}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue