Skip to content

Commit e22e858

Browse files
committed
Move more scrape-examples logic from JS to rust
Fix failing test Add missing backslash Fix padding issue with horizontal scrollbar
1 parent bb383ed commit e22e858

File tree

7 files changed

+64
-63
lines changed

7 files changed

+64
-63
lines changed

src/librustdoc/html/highlight.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ fn string<T: Display>(
691691
// https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
692692
match href {
693693
LinkFromSrc::Local(span) => context
694-
.href_from_span(*span)
694+
.href_from_span(*span, true)
695695
.map(|s| format!("{}{}", context_info.root_path, s)),
696696
LinkFromSrc::External(def_id) => {
697697
format::href_with_root_path(*def_id, context, Some(context_info.root_path))

src/librustdoc/html/render/context.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,10 @@ impl<'tcx> Context<'tcx> {
295295
/// may happen, for example, with externally inlined items where the source
296296
/// of their crate documentation isn't known.
297297
pub(super) fn src_href(&self, item: &clean::Item) -> Option<String> {
298-
self.href_from_span(item.span(self.tcx()))
298+
self.href_from_span(item.span(self.tcx()), true)
299299
}
300300

301-
crate fn href_from_span(&self, span: clean::Span) -> Option<String> {
301+
crate fn href_from_span(&self, span: clean::Span, with_lines: bool) -> Option<String> {
302302
if span.is_dummy() {
303303
return None;
304304
}
@@ -345,16 +345,26 @@ impl<'tcx> Context<'tcx> {
345345
(&*symbol, &path)
346346
};
347347

348-
let loline = span.lo(self.sess()).line;
349-
let hiline = span.hi(self.sess()).line;
350-
let lines =
351-
if loline == hiline { loline.to_string() } else { format!("{}-{}", loline, hiline) };
348+
let anchor = if with_lines {
349+
let loline = span.lo(self.sess()).line;
350+
let hiline = span.hi(self.sess()).line;
351+
format!(
352+
"#{}",
353+
if loline == hiline {
354+
loline.to_string()
355+
} else {
356+
format!("{}-{}", loline, hiline)
357+
}
358+
)
359+
} else {
360+
"".to_string()
361+
};
352362
Some(format!(
353-
"{root}src/{krate}/{path}#{lines}",
363+
"{root}src/{krate}/{path}{anchor}",
354364
root = Escape(&root),
355365
krate = krate,
356366
path = path,
357-
lines = lines
367+
anchor = anchor
358368
))
359369
}
360370
}

src/librustdoc/html/render/mod.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2475,12 +2475,11 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
24752475
};
24762476

24772477
// Generate a unique ID so users can link to this section for a given method
2478-
// FIXME: this should use init_id_map instead of derive
24792478
let id = cx.id_map.borrow_mut().derive("scraped-examples");
24802479
write!(
24812480
w,
24822481
"<div class=\"docblock scraped-example-list\">\
2483-
<span></span>
2482+
<span></span>\
24842483
<h5 id=\"{id}\" class=\"section-header\">\
24852484
<a href=\"#{id}\">Examples found in repository</a>\
24862485
</h5>",
@@ -2516,42 +2515,51 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
25162515

25172516
// The call locations need to be updated to reflect that the size of the program has changed.
25182517
// Specifically, the ranges are all subtracted by `byte_min` since that's the new zero point.
2519-
let (byte_ranges, line_ranges): (Vec<_>, Vec<_>) = call_data
2518+
let (mut byte_ranges, line_ranges): (Vec<_>, Vec<_>) = call_data
25202519
.locations
25212520
.iter()
25222521
.map(|loc| {
25232522
let (byte_lo, byte_hi) = loc.call_expr.byte_span;
25242523
let (line_lo, line_hi) = loc.call_expr.line_span;
2525-
((byte_lo - byte_min, byte_hi - byte_min), (line_lo - line_min, line_hi - line_min))
2524+
let byte_range = (byte_lo - byte_min, byte_hi - byte_min);
2525+
let line_range = (line_lo - line_min, line_hi - line_min);
2526+
let (anchor, line_title) = if line_lo == line_hi {
2527+
(format!("{}", line_lo + 1), format!("line {}", line_lo + 1))
2528+
} else {
2529+
(
2530+
format!("{}-{}", line_lo + 1, line_hi + 1),
2531+
format!("lines {}-{}", line_lo + 1, line_hi + 1),
2532+
)
2533+
};
2534+
let line_url = format!("{}{}#{}", cx.root_path(), call_data.url, anchor);
2535+
2536+
(byte_range, (line_range, line_url, line_title))
25262537
})
25272538
.unzip();
25282539

2529-
let (init_min, init_max) = line_ranges[0];
2530-
let line_range = if init_min == init_max {
2531-
format!("line {}", init_min + line_min + 1)
2532-
} else {
2533-
format!("lines {}-{}", init_min + line_min + 1, init_max + line_min + 1)
2534-
};
2535-
2540+
let (_, init_url, init_title) = &line_ranges[0];
25362541
let needs_expansion = line_max - line_min > NUM_VISIBLE_LINES;
2542+
let locations_encoded = serde_json::to_string(&line_ranges).unwrap();
25372543

25382544
write!(
25392545
w,
25402546
"<div class=\"scraped-example {expanded_cls}\" data-locs=\"{locations}\">\
25412547
<div class=\"scraped-example-title\">\
2542-
{name} (<a href=\"{root}{url}\">{line_range}</a>)\
2548+
{name} (<a href=\"{url}\">{title}</a>)\
25432549
</div>\
25442550
<div class=\"code-wrapper\">",
2545-
root = cx.root_path(),
2546-
url = call_data.url,
2547-
name = call_data.display_name,
2548-
line_range = line_range,
25492551
expanded_cls = if needs_expansion { "" } else { "expanded" },
2552+
name = call_data.display_name,
2553+
url = init_url,
2554+
title = init_title,
25502555
// The locations are encoded as a data attribute, so they can be read
25512556
// later by the JS for interactions.
2552-
locations = serde_json::to_string(&line_ranges).unwrap(),
2557+
locations = Escape(&locations_encoded)
25532558
);
2554-
write!(w, r#"<span class="prev">&pr;</span> <span class="next">&sc;</span>"#);
2559+
2560+
if line_ranges.len() > 1 {
2561+
write!(w, r#"<span class="prev">&pr;</span> <span class="next">&sc;</span>"#);
2562+
}
25552563

25562564
if needs_expansion {
25572565
write!(w, r#"<span class="expand">&varr;</span>"#);
@@ -2580,6 +2588,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
25802588
let root_path = vec!["../"; cx.current.len() - 1].join("");
25812589

25822590
let mut decoration_info = FxHashMap::default();
2591+
decoration_info.insert("highlight focus", vec![byte_ranges.remove(0)]);
25832592
decoration_info.insert("highlight", byte_ranges);
25842593

25852594
sources::print_src(

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,6 +1986,7 @@ details.undocumented[open] > summary::before {
19861986
.scraped-example:not(.expanded) .code-wrapper .example-wrap pre.rust {
19871987
overflow-y: hidden;
19881988
max-height: 240px;
1989+
padding-bottom: 0;
19891990
}
19901991

19911992
.scraped-example .code-wrapper .prev {

src/librustdoc/html/static/js/scrape-examples.js

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,41 +15,23 @@
1515

1616
function updateScrapedExample(example) {
1717
var locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
18-
var first_line_no = example.querySelector('.line-numbers > span:first-child');
19-
var offset = parseInt(first_line_no.innerHTML) - 1;
20-
2118
var locIndex = 0;
2219
var highlights = example.querySelectorAll('.highlight');
2320
var link = example.querySelector('.scraped-example-title a');
24-
addClass(highlights[0], 'focus');
21+
2522
if (locs.length > 1) {
2623
// Toggle through list of examples in a given file
27-
var onChangeLoc = function(f) {
24+
var onChangeLoc = function(changeIndex) {
2825
removeClass(highlights[locIndex], 'focus');
29-
f();
30-
scrollToLoc(example, locs[locIndex]);
26+
changeIndex();
27+
scrollToLoc(example, locs[locIndex][0]);
3128
addClass(highlights[locIndex], 'focus');
3229

33-
var curLoc = locs[locIndex];
34-
var minLine = curLoc[0] + offset + 1;
35-
var maxLine = curLoc[1] + offset + 1;
36-
37-
var text;
38-
var anchor;
39-
if (minLine == maxLine) {
40-
text = 'line ' + minLine.toString();
41-
anchor = minLine.toString();
42-
} else {
43-
var range = minLine.toString() + '-' + maxLine.toString();
44-
text = 'lines ' + range;
45-
anchor = range;
46-
}
47-
48-
var url = new URL(link.href);
49-
url.hash = anchor;
30+
var url = locs[locIndex][1];
31+
var title = locs[locIndex][2];
5032

51-
link.href = url.toString();
52-
link.innerHTML = text;
33+
link.href = url;
34+
link.innerHTML = title;
5335
};
5436

5537
example.querySelector('.prev')
@@ -61,28 +43,26 @@
6143

6244
example.querySelector('.next')
6345
.addEventListener('click', function() {
64-
onChangeLoc(function() { locIndex = (locIndex + 1) % locs.length; });
46+
onChangeLoc(function() {
47+
locIndex = (locIndex + 1) % locs.length;
48+
});
6549
});
66-
} else {
67-
// Remove buttons if there's only one example in the file
68-
example.querySelector('.prev').remove();
69-
example.querySelector('.next').remove();
7050
}
7151

7252
var expandButton = example.querySelector('.expand');
7353
if (expandButton) {
7454
expandButton.addEventListener('click', function () {
7555
if (hasClass(example, "expanded")) {
7656
removeClass(example, "expanded");
77-
scrollToLoc(example, locs[0]);
57+
scrollToLoc(example, locs[0][0]);
7858
} else {
7959
addClass(example, "expanded");
8060
}
8161
});
8262
}
8363

8464
// Start with the first example in view
85-
scrollToLoc(example, locs[0]);
65+
scrollToLoc(example, locs[0][0]);
8666
}
8767

8868
var firstExamples = document.querySelectorAll('.scraped-example-list > .scraped-example');

src/librustdoc/scrape_examples.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ where
171171
let cx = &self.cx;
172172
let mk_call_data = || {
173173
let clean_span = crate::clean::types::Span::new(span);
174-
let url = cx.href_from_span(clean_span).unwrap();
174+
let url = cx.href_from_span(clean_span, false).unwrap();
175175
let display_name = file_path.display().to_string();
176176
let edition = span.edition();
177177
CallData { locations: Vec::new(), url, display_name, edition }
@@ -233,6 +233,7 @@ crate fn run(
233233
Ok(())
234234
}
235235

236+
// Note: the Handler must be passed in explicitly because sess isn't available while parsing options
236237
crate fn load_call_locations(
237238
with_examples: Vec<String>,
238239
diag: &rustc_errors::Handler,

src/test/run-make/rustdoc-scrape-examples-remap/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// @has foobar/b/fn.foo.html '//*[@class="scraped-example"]' 'ex.rs'
2-
// @has foobar/c/fn.foo.html '//*[@class="scraped-example"]' 'ex.rs'
1+
// @has foobar/b/fn.foo.html '//*[@class="scraped-example expanded"]' 'ex.rs'
2+
// @has foobar/c/fn.foo.html '//*[@class="scraped-example expanded"]' 'ex.rs'
33

44
#[path = "a.rs"]
55
pub mod b;

0 commit comments

Comments
 (0)