Move more scrape-examples logic from JS to rust
Fix failing test Add missing backslash Fix padding issue with horizontal scrollbar
This commit is contained in:
parent
bb383edb69
commit
e22e858687
7 changed files with 64 additions and 63 deletions
|
@ -691,7 +691,7 @@ fn string<T: Display>(
|
||||||
// https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
|
// https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
|
||||||
match href {
|
match href {
|
||||||
LinkFromSrc::Local(span) => context
|
LinkFromSrc::Local(span) => context
|
||||||
.href_from_span(*span)
|
.href_from_span(*span, true)
|
||||||
.map(|s| format!("{}{}", context_info.root_path, s)),
|
.map(|s| format!("{}{}", context_info.root_path, s)),
|
||||||
LinkFromSrc::External(def_id) => {
|
LinkFromSrc::External(def_id) => {
|
||||||
format::href_with_root_path(*def_id, context, Some(context_info.root_path))
|
format::href_with_root_path(*def_id, context, Some(context_info.root_path))
|
||||||
|
|
|
@ -295,10 +295,10 @@ impl<'tcx> Context<'tcx> {
|
||||||
/// may happen, for example, with externally inlined items where the source
|
/// may happen, for example, with externally inlined items where the source
|
||||||
/// of their crate documentation isn't known.
|
/// of their crate documentation isn't known.
|
||||||
pub(super) fn src_href(&self, item: &clean::Item) -> Option<String> {
|
pub(super) fn src_href(&self, item: &clean::Item) -> Option<String> {
|
||||||
self.href_from_span(item.span(self.tcx()))
|
self.href_from_span(item.span(self.tcx()), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn href_from_span(&self, span: clean::Span) -> Option<String> {
|
crate fn href_from_span(&self, span: clean::Span, with_lines: bool) -> Option<String> {
|
||||||
if span.is_dummy() {
|
if span.is_dummy() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -345,16 +345,26 @@ impl<'tcx> Context<'tcx> {
|
||||||
(&*symbol, &path)
|
(&*symbol, &path)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let anchor = if with_lines {
|
||||||
let loline = span.lo(self.sess()).line;
|
let loline = span.lo(self.sess()).line;
|
||||||
let hiline = span.hi(self.sess()).line;
|
let hiline = span.hi(self.sess()).line;
|
||||||
let lines =
|
format!(
|
||||||
if loline == hiline { loline.to_string() } else { format!("{}-{}", loline, hiline) };
|
"#{}",
|
||||||
|
if loline == hiline {
|
||||||
|
loline.to_string()
|
||||||
|
} else {
|
||||||
|
format!("{}-{}", loline, hiline)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
Some(format!(
|
Some(format!(
|
||||||
"{root}src/{krate}/{path}#{lines}",
|
"{root}src/{krate}/{path}{anchor}",
|
||||||
root = Escape(&root),
|
root = Escape(&root),
|
||||||
krate = krate,
|
krate = krate,
|
||||||
path = path,
|
path = path,
|
||||||
lines = lines
|
anchor = anchor
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2475,12 +2475,11 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate a unique ID so users can link to this section for a given method
|
// Generate a unique ID so users can link to this section for a given method
|
||||||
// FIXME: this should use init_id_map instead of derive
|
|
||||||
let id = cx.id_map.borrow_mut().derive("scraped-examples");
|
let id = cx.id_map.borrow_mut().derive("scraped-examples");
|
||||||
write!(
|
write!(
|
||||||
w,
|
w,
|
||||||
"<div class=\"docblock scraped-example-list\">\
|
"<div class=\"docblock scraped-example-list\">\
|
||||||
<span></span>
|
<span></span>\
|
||||||
<h5 id=\"{id}\" class=\"section-header\">\
|
<h5 id=\"{id}\" class=\"section-header\">\
|
||||||
<a href=\"#{id}\">Examples found in repository</a>\
|
<a href=\"#{id}\">Examples found in repository</a>\
|
||||||
</h5>",
|
</h5>",
|
||||||
|
@ -2516,42 +2515,51 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
|
||||||
|
|
||||||
// The call locations need to be updated to reflect that the size of the program has changed.
|
// The call locations need to be updated to reflect that the size of the program has changed.
|
||||||
// Specifically, the ranges are all subtracted by `byte_min` since that's the new zero point.
|
// Specifically, the ranges are all subtracted by `byte_min` since that's the new zero point.
|
||||||
let (byte_ranges, line_ranges): (Vec<_>, Vec<_>) = call_data
|
let (mut byte_ranges, line_ranges): (Vec<_>, Vec<_>) = call_data
|
||||||
.locations
|
.locations
|
||||||
.iter()
|
.iter()
|
||||||
.map(|loc| {
|
.map(|loc| {
|
||||||
let (byte_lo, byte_hi) = loc.call_expr.byte_span;
|
let (byte_lo, byte_hi) = loc.call_expr.byte_span;
|
||||||
let (line_lo, line_hi) = loc.call_expr.line_span;
|
let (line_lo, line_hi) = loc.call_expr.line_span;
|
||||||
((byte_lo - byte_min, byte_hi - byte_min), (line_lo - line_min, line_hi - line_min))
|
let byte_range = (byte_lo - byte_min, byte_hi - byte_min);
|
||||||
|
let line_range = (line_lo - line_min, line_hi - line_min);
|
||||||
|
let (anchor, line_title) = if line_lo == line_hi {
|
||||||
|
(format!("{}", line_lo + 1), format!("line {}", line_lo + 1))
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
format!("{}-{}", line_lo + 1, line_hi + 1),
|
||||||
|
format!("lines {}-{}", line_lo + 1, line_hi + 1),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let line_url = format!("{}{}#{}", cx.root_path(), call_data.url, anchor);
|
||||||
|
|
||||||
|
(byte_range, (line_range, line_url, line_title))
|
||||||
})
|
})
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
let (init_min, init_max) = line_ranges[0];
|
let (_, init_url, init_title) = &line_ranges[0];
|
||||||
let line_range = if init_min == init_max {
|
|
||||||
format!("line {}", init_min + line_min + 1)
|
|
||||||
} else {
|
|
||||||
format!("lines {}-{}", init_min + line_min + 1, init_max + line_min + 1)
|
|
||||||
};
|
|
||||||
|
|
||||||
let needs_expansion = line_max - line_min > NUM_VISIBLE_LINES;
|
let needs_expansion = line_max - line_min > NUM_VISIBLE_LINES;
|
||||||
|
let locations_encoded = serde_json::to_string(&line_ranges).unwrap();
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
w,
|
w,
|
||||||
"<div class=\"scraped-example {expanded_cls}\" data-locs=\"{locations}\">\
|
"<div class=\"scraped-example {expanded_cls}\" data-locs=\"{locations}\">\
|
||||||
<div class=\"scraped-example-title\">\
|
<div class=\"scraped-example-title\">\
|
||||||
{name} (<a href=\"{root}{url}\">{line_range}</a>)\
|
{name} (<a href=\"{url}\">{title}</a>)\
|
||||||
</div>\
|
</div>\
|
||||||
<div class=\"code-wrapper\">",
|
<div class=\"code-wrapper\">",
|
||||||
root = cx.root_path(),
|
|
||||||
url = call_data.url,
|
|
||||||
name = call_data.display_name,
|
|
||||||
line_range = line_range,
|
|
||||||
expanded_cls = if needs_expansion { "" } else { "expanded" },
|
expanded_cls = if needs_expansion { "" } else { "expanded" },
|
||||||
|
name = call_data.display_name,
|
||||||
|
url = init_url,
|
||||||
|
title = init_title,
|
||||||
// The locations are encoded as a data attribute, so they can be read
|
// The locations are encoded as a data attribute, so they can be read
|
||||||
// later by the JS for interactions.
|
// later by the JS for interactions.
|
||||||
locations = serde_json::to_string(&line_ranges).unwrap(),
|
locations = Escape(&locations_encoded)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if line_ranges.len() > 1 {
|
||||||
write!(w, r#"<span class="prev">≺</span> <span class="next">≻</span>"#);
|
write!(w, r#"<span class="prev">≺</span> <span class="next">≻</span>"#);
|
||||||
|
}
|
||||||
|
|
||||||
if needs_expansion {
|
if needs_expansion {
|
||||||
write!(w, r#"<span class="expand">↕</span>"#);
|
write!(w, r#"<span class="expand">↕</span>"#);
|
||||||
|
@ -2580,6 +2588,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
|
||||||
let root_path = vec!["../"; cx.current.len() - 1].join("");
|
let root_path = vec!["../"; cx.current.len() - 1].join("");
|
||||||
|
|
||||||
let mut decoration_info = FxHashMap::default();
|
let mut decoration_info = FxHashMap::default();
|
||||||
|
decoration_info.insert("highlight focus", vec![byte_ranges.remove(0)]);
|
||||||
decoration_info.insert("highlight", byte_ranges);
|
decoration_info.insert("highlight", byte_ranges);
|
||||||
|
|
||||||
sources::print_src(
|
sources::print_src(
|
||||||
|
|
|
@ -1986,6 +1986,7 @@ details.undocumented[open] > summary::before {
|
||||||
.scraped-example:not(.expanded) .code-wrapper .example-wrap pre.rust {
|
.scraped-example:not(.expanded) .code-wrapper .example-wrap pre.rust {
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
max-height: 240px;
|
max-height: 240px;
|
||||||
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scraped-example .code-wrapper .prev {
|
.scraped-example .code-wrapper .prev {
|
||||||
|
|
|
@ -15,41 +15,23 @@
|
||||||
|
|
||||||
function updateScrapedExample(example) {
|
function updateScrapedExample(example) {
|
||||||
var locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
|
var locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
|
||||||
var first_line_no = example.querySelector('.line-numbers > span:first-child');
|
|
||||||
var offset = parseInt(first_line_no.innerHTML) - 1;
|
|
||||||
|
|
||||||
var locIndex = 0;
|
var locIndex = 0;
|
||||||
var highlights = example.querySelectorAll('.highlight');
|
var highlights = example.querySelectorAll('.highlight');
|
||||||
var link = example.querySelector('.scraped-example-title a');
|
var link = example.querySelector('.scraped-example-title a');
|
||||||
addClass(highlights[0], 'focus');
|
|
||||||
if (locs.length > 1) {
|
if (locs.length > 1) {
|
||||||
// Toggle through list of examples in a given file
|
// Toggle through list of examples in a given file
|
||||||
var onChangeLoc = function(f) {
|
var onChangeLoc = function(changeIndex) {
|
||||||
removeClass(highlights[locIndex], 'focus');
|
removeClass(highlights[locIndex], 'focus');
|
||||||
f();
|
changeIndex();
|
||||||
scrollToLoc(example, locs[locIndex]);
|
scrollToLoc(example, locs[locIndex][0]);
|
||||||
addClass(highlights[locIndex], 'focus');
|
addClass(highlights[locIndex], 'focus');
|
||||||
|
|
||||||
var curLoc = locs[locIndex];
|
var url = locs[locIndex][1];
|
||||||
var minLine = curLoc[0] + offset + 1;
|
var title = locs[locIndex][2];
|
||||||
var maxLine = curLoc[1] + offset + 1;
|
|
||||||
|
|
||||||
var text;
|
link.href = url;
|
||||||
var anchor;
|
link.innerHTML = title;
|
||||||
if (minLine == maxLine) {
|
|
||||||
text = 'line ' + minLine.toString();
|
|
||||||
anchor = minLine.toString();
|
|
||||||
} else {
|
|
||||||
var range = minLine.toString() + '-' + maxLine.toString();
|
|
||||||
text = 'lines ' + range;
|
|
||||||
anchor = range;
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = new URL(link.href);
|
|
||||||
url.hash = anchor;
|
|
||||||
|
|
||||||
link.href = url.toString();
|
|
||||||
link.innerHTML = text;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
example.querySelector('.prev')
|
example.querySelector('.prev')
|
||||||
|
@ -61,12 +43,10 @@
|
||||||
|
|
||||||
example.querySelector('.next')
|
example.querySelector('.next')
|
||||||
.addEventListener('click', function() {
|
.addEventListener('click', function() {
|
||||||
onChangeLoc(function() { locIndex = (locIndex + 1) % locs.length; });
|
onChangeLoc(function() {
|
||||||
|
locIndex = (locIndex + 1) % locs.length;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
// Remove buttons if there's only one example in the file
|
|
||||||
example.querySelector('.prev').remove();
|
|
||||||
example.querySelector('.next').remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var expandButton = example.querySelector('.expand');
|
var expandButton = example.querySelector('.expand');
|
||||||
|
@ -74,7 +54,7 @@
|
||||||
expandButton.addEventListener('click', function () {
|
expandButton.addEventListener('click', function () {
|
||||||
if (hasClass(example, "expanded")) {
|
if (hasClass(example, "expanded")) {
|
||||||
removeClass(example, "expanded");
|
removeClass(example, "expanded");
|
||||||
scrollToLoc(example, locs[0]);
|
scrollToLoc(example, locs[0][0]);
|
||||||
} else {
|
} else {
|
||||||
addClass(example, "expanded");
|
addClass(example, "expanded");
|
||||||
}
|
}
|
||||||
|
@ -82,7 +62,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start with the first example in view
|
// Start with the first example in view
|
||||||
scrollToLoc(example, locs[0]);
|
scrollToLoc(example, locs[0][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstExamples = document.querySelectorAll('.scraped-example-list > .scraped-example');
|
var firstExamples = document.querySelectorAll('.scraped-example-list > .scraped-example');
|
||||||
|
|
|
@ -171,7 +171,7 @@ where
|
||||||
let cx = &self.cx;
|
let cx = &self.cx;
|
||||||
let mk_call_data = || {
|
let mk_call_data = || {
|
||||||
let clean_span = crate::clean::types::Span::new(span);
|
let clean_span = crate::clean::types::Span::new(span);
|
||||||
let url = cx.href_from_span(clean_span).unwrap();
|
let url = cx.href_from_span(clean_span, false).unwrap();
|
||||||
let display_name = file_path.display().to_string();
|
let display_name = file_path.display().to_string();
|
||||||
let edition = span.edition();
|
let edition = span.edition();
|
||||||
CallData { locations: Vec::new(), url, display_name, edition }
|
CallData { locations: Vec::new(), url, display_name, edition }
|
||||||
|
@ -233,6 +233,7 @@ crate fn run(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: the Handler must be passed in explicitly because sess isn't available while parsing options
|
||||||
crate fn load_call_locations(
|
crate fn load_call_locations(
|
||||||
with_examples: Vec<String>,
|
with_examples: Vec<String>,
|
||||||
diag: &rustc_errors::Handler,
|
diag: &rustc_errors::Handler,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// @has foobar/b/fn.foo.html '//*[@class="scraped-example"]' 'ex.rs'
|
// @has foobar/b/fn.foo.html '//*[@class="scraped-example expanded"]' 'ex.rs'
|
||||||
// @has foobar/c/fn.foo.html '//*[@class="scraped-example"]' 'ex.rs'
|
// @has foobar/c/fn.foo.html '//*[@class="scraped-example expanded"]' 'ex.rs'
|
||||||
|
|
||||||
#[path = "a.rs"]
|
#[path = "a.rs"]
|
||||||
pub mod b;
|
pub mod b;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue