Skip to content

Commit bb383ed

Browse files
committed
Move some expansion logic into generation-time, fix section header links, remove ID from line numbers, fix horizontal scrolling on non-expanded elements
1 parent 5584c79 commit bb383ed

File tree

4 files changed

+54
-40
lines changed

4 files changed

+54
-40
lines changed

src/librustdoc/html/render/mod.rs

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2461,6 +2461,7 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
24612461
}
24622462

24632463
const MAX_FULL_EXAMPLES: usize = 5;
2464+
const NUM_VISIBLE_LINES: usize = 10;
24642465

24652466
/// Generates the HTML for example call locations generated via the --scrape-examples flag.
24662467
fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item: &clean::Item) {
@@ -2480,10 +2481,10 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
24802481
w,
24812482
"<div class=\"docblock scraped-example-list\">\
24822483
<span></span>
2483-
<h5 id=\"scraped-examples\" class=\"section-header\">\
2484-
<a href=\"#{}\">Examples found in repository</a>\
2484+
<h5 id=\"{id}\" class=\"section-header\">\
2485+
<a href=\"#{id}\">Examples found in repository</a>\
24852486
</h5>",
2486-
id
2487+
id = id
24872488
);
24882489

24892490
// Generate the HTML for a single example, being the title and code block
@@ -2503,54 +2504,58 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
25032504
assert!(!call_data.locations.is_empty());
25042505
let min_loc =
25052506
call_data.locations.iter().min_by_key(|loc| loc.enclosing_item.byte_span.0).unwrap();
2506-
let (byte_offset, _) = min_loc.enclosing_item.byte_span;
2507-
let (line_offset, _) = min_loc.enclosing_item.line_span;
2508-
let byte_ceiling =
2509-
call_data.locations.iter().map(|loc| loc.enclosing_item.byte_span.1).max().unwrap();
2507+
let byte_min = min_loc.enclosing_item.byte_span.0;
2508+
let line_min = min_loc.enclosing_item.line_span.0;
2509+
let max_loc =
2510+
call_data.locations.iter().max_by_key(|loc| loc.enclosing_item.byte_span.1).unwrap();
2511+
let byte_max = max_loc.enclosing_item.byte_span.1;
2512+
let line_max = max_loc.enclosing_item.line_span.1;
25102513

25112514
// The output code is limited to that byte range.
2512-
let contents_subset = &contents[(byte_offset as usize)..(byte_ceiling as usize)];
2515+
let contents_subset = &contents[(byte_min as usize)..(byte_max as usize)];
25132516

25142517
// The call locations need to be updated to reflect that the size of the program has changed.
2515-
// Specifically, the ranges are all subtracted by `byte_offset` since that's the new zero point.
2518+
// Specifically, the ranges are all subtracted by `byte_min` since that's the new zero point.
25162519
let (byte_ranges, line_ranges): (Vec<_>, Vec<_>) = call_data
25172520
.locations
25182521
.iter()
25192522
.map(|loc| {
25202523
let (byte_lo, byte_hi) = loc.call_expr.byte_span;
25212524
let (line_lo, line_hi) = loc.call_expr.line_span;
2522-
(
2523-
(byte_lo - byte_offset, byte_hi - byte_offset),
2524-
(line_lo - line_offset, line_hi - line_offset),
2525-
)
2525+
((byte_lo - byte_min, byte_hi - byte_min), (line_lo - line_min, line_hi - line_min))
25262526
})
25272527
.unzip();
25282528

25292529
let (init_min, init_max) = line_ranges[0];
25302530
let line_range = if init_min == init_max {
2531-
format!("line {}", init_min + line_offset + 1)
2531+
format!("line {}", init_min + line_min + 1)
25322532
} else {
2533-
format!("lines {}-{}", init_min + line_offset + 1, init_max + line_offset + 1)
2533+
format!("lines {}-{}", init_min + line_min + 1, init_max + line_min + 1)
25342534
};
25352535

2536+
let needs_expansion = line_max - line_min > NUM_VISIBLE_LINES;
2537+
25362538
write!(
25372539
w,
2538-
"<div class=\"scraped-example\" data-locs=\"{locations}\" data-offset=\"{offset}\">\
2540+
"<div class=\"scraped-example {expanded_cls}\" data-locs=\"{locations}\">\
25392541
<div class=\"scraped-example-title\">\
2540-
{name} (<a href=\"{root}{url}\" target=\"_blank\">{line_range}</a>)\
2542+
{name} (<a href=\"{root}{url}\">{line_range}</a>)\
25412543
</div>\
25422544
<div class=\"code-wrapper\">",
25432545
root = cx.root_path(),
25442546
url = call_data.url,
25452547
name = call_data.display_name,
25462548
line_range = line_range,
2547-
offset = line_offset,
2549+
expanded_cls = if needs_expansion { "" } else { "expanded" },
25482550
// The locations are encoded as a data attribute, so they can be read
25492551
// later by the JS for interactions.
25502552
locations = serde_json::to_string(&line_ranges).unwrap(),
25512553
);
25522554
write!(w, r#"<span class="prev">&pr;</span> <span class="next">&sc;</span>"#);
2553-
write!(w, r#"<span class="expand">&varr;</span>"#);
2555+
2556+
if needs_expansion {
2557+
write!(w, r#"<span class="expand">&varr;</span>"#);
2558+
}
25542559

25552560
// Look for the example file in the source map if it exists, otherwise return a dummy span
25562561
let file_span = (|| {
@@ -2565,8 +2570,8 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
25652570
_ => false,
25662571
})?;
25672572
Some(rustc_span::Span::with_root_ctxt(
2568-
file.start_pos + BytePos(byte_offset),
2569-
file.start_pos + BytePos(byte_ceiling),
2573+
file.start_pos + BytePos(byte_min),
2574+
file.start_pos + BytePos(byte_max),
25702575
))
25712576
})()
25722577
.unwrap_or(rustc_span::DUMMY_SP);
@@ -2584,8 +2589,8 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
25842589
file_span,
25852590
cx,
25862591
&root_path,
2587-
Some(line_offset),
25882592
Some(highlight::DecorationInfo(decoration_info)),
2593+
sources::SourceContext::Embedded { offset: line_min },
25892594
);
25902595
write!(w, "</div></div>");
25912596

@@ -2648,7 +2653,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
26482653
it.for_each(|(_, call_data)| {
26492654
write!(
26502655
w,
2651-
r#"<li><a href="{root}{url}" target="_blank">{name}</a></li>"#,
2656+
r#"<li><a href="{root}{url}">{name}</a></li>"#,
26522657
root = cx.root_path(),
26532658
url = call_data.url,
26542659
name = call_data.display_name

src/librustdoc/html/sources.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ impl SourceCollector<'_, 'tcx> {
212212
&self.cx,
213213
&root_path,
214214
None,
215-
None,
215+
SourceContext::Standalone,
216216
)
217217
},
218218
&self.cx.shared.style_files,
@@ -250,6 +250,11 @@ where
250250
}
251251
}
252252

253+
crate enum SourceContext {
254+
Standalone,
255+
Embedded { offset: usize },
256+
}
257+
253258
/// Wrapper struct to render the source code of a file. This will do things like
254259
/// adding line numbers to the left-hand side.
255260
crate fn print_src(
@@ -259,8 +264,8 @@ crate fn print_src(
259264
file_span: rustc_span::Span,
260265
context: &Context<'_>,
261266
root_path: &str,
262-
offset: Option<usize>,
263267
decoration_info: Option<highlight::DecorationInfo>,
268+
source_context: SourceContext,
264269
) {
265270
let lines = s.lines().count();
266271
let mut line_numbers = Buffer::empty_from(buf);
@@ -271,9 +276,15 @@ crate fn print_src(
271276
tmp /= 10;
272277
}
273278
line_numbers.write_str("<pre class=\"line-numbers\">");
274-
let offset = offset.unwrap_or(0);
275279
for i in 1..=lines {
276-
writeln!(line_numbers, "<span id=\"{0}\">{0:1$}</span>", i + offset, cols);
280+
match source_context {
281+
SourceContext::Standalone => {
282+
writeln!(line_numbers, "<span id=\"{0}\">{0:1$}</span>", i, cols)
283+
}
284+
SourceContext::Embedded { offset } => {
285+
writeln!(line_numbers, "<span>{0:1$}</span>", i + offset, cols)
286+
}
287+
}
277288
}
278289
line_numbers.write_str("</pre>");
279290
highlight::render_with_highlighting(

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,12 +1978,16 @@ details.undocumented[open] > summary::before {
19781978
font-family: 'Fira Sans';
19791979
}
19801980

1981-
.scraped-example:not(.expanded) .code-wrapper pre.line-numbers,
1982-
.scraped-example:not(.expanded) .code-wrapper .example-wrap pre.rust {
1981+
.scraped-example:not(.expanded) .code-wrapper pre.line-numbers {
19831982
overflow: hidden;
19841983
max-height: 240px;
19851984
}
19861985

1986+
.scraped-example:not(.expanded) .code-wrapper .example-wrap pre.rust {
1987+
overflow-y: hidden;
1988+
max-height: 240px;
1989+
}
1990+
19871991
.scraped-example .code-wrapper .prev {
19881992
position: absolute;
19891993
top: 0.25em;
@@ -2019,7 +2023,7 @@ details.undocumented[open] > summary::before {
20192023
.scraped-example:not(.expanded) .code-wrapper:before {
20202024
content: " ";
20212025
width: 100%;
2022-
height: 10px;
2026+
height: 5px;
20232027
position: absolute;
20242028
z-index: 100;
20252029
top: 0;
@@ -2029,7 +2033,7 @@ details.undocumented[open] > summary::before {
20292033
.scraped-example:not(.expanded) .code-wrapper:after {
20302034
content: " ";
20312035
width: 100%;
2032-
height: 10px;
2036+
height: 5px;
20332037
position: absolute;
20342038
z-index: 100;
20352039
bottom: 0;

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

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515

1616
function updateScrapedExample(example) {
1717
var locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
18-
var offset = parseInt(example.attributes.getNamedItem("data-offset").textContent);
18+
var first_line_no = example.querySelector('.line-numbers > span:first-child');
19+
var offset = parseInt(first_line_no.innerHTML) - 1;
1920

2021
var locIndex = 0;
2122
var highlights = example.querySelectorAll('.highlight');
@@ -68,11 +69,8 @@
6869
example.querySelector('.next').remove();
6970
}
7071

71-
var codeEl = example.querySelector('.rust');
72-
var codeOverflows = codeEl.scrollHeight > codeEl.clientHeight;
7372
var expandButton = example.querySelector('.expand');
74-
if (codeOverflows) {
75-
// If file is larger than default height, give option to expand the viewer
73+
if (expandButton) {
7674
expandButton.addEventListener('click', function () {
7775
if (hasClass(example, "expanded")) {
7876
removeClass(example, "expanded");
@@ -81,10 +79,6 @@
8179
addClass(example, "expanded");
8280
}
8381
});
84-
} else {
85-
// Otherwise remove expansion buttons
86-
addClass(example, 'expanded');
87-
expandButton.remove();
8882
}
8983

9084
// Start with the first example in view

0 commit comments

Comments
 (0)