diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 3666767a9d9c..23ce3b131bbd 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2717,6 +2717,30 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
// The output code is limited to that byte range.
let contents_subset = &contents[(byte_min as usize)..(byte_max as usize)];
+ // Given a call-site range, return the set of sub-ranges that exclude leading whitespace
+ // when the range spans multiple lines.
+ let strip_leading_whitespace = |(lo, hi): (u32, u32)| -> Vec<(u32, u32)> {
+ let contents_range = &contents_subset[(lo as usize)..(hi as usize)];
+ let mut ignoring_whitespace = false;
+ let mut ranges = Vec::new();
+ let mut cur_lo = 0;
+ for (idx, chr) in contents_range.char_indices() {
+ let idx = idx as u32;
+ if ignoring_whitespace {
+ if !chr.is_whitespace() {
+ ignoring_whitespace = false;
+ cur_lo = idx;
+ }
+ } else if chr == '\n' {
+ ranges.push((lo + cur_lo, lo + idx));
+ cur_lo = idx;
+ ignoring_whitespace = true;
+ }
+ }
+ ranges.push((lo + cur_lo, hi));
+ ranges
+ };
+
// 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.
let (mut byte_ranges, line_ranges): (Vec<_>, Vec<_>) = call_data
@@ -2726,10 +2750,12 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
let (byte_lo, byte_hi) = loc.call_expr.byte_span;
let (line_lo, line_hi) = loc.call_expr.line_span;
let byte_range = (byte_lo - byte_min, byte_hi - byte_min);
+ let byte_ranges = strip_leading_whitespace(byte_range);
+
let line_range = (line_lo - line_min, line_hi - line_min);
let (line_url, line_title) = link_to_loc(call_data, loc);
- (byte_range, (line_range, line_url, line_title))
+ (byte_ranges, (line_range, line_url, line_title))
})
.unzip();
@@ -2784,8 +2810,8 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
let root_path = vec!["../"; cx.current.len() - 1].join("");
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 focus", byte_ranges.remove(0));
+ decoration_info.insert("highlight", byte_ranges.into_iter().flatten().collect());
sources::print_src(
w,
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index ee265b8c4b54..42b66c70c4cb 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -2038,17 +2038,16 @@ details.rustdoc-toggle[open] > summary.hideme::after {
font-family: 'Fira Sans';
}
-.scraped-example:not(.expanded) .code-wrapper pre.line-numbers {
- overflow: hidden;
- max-height: 240px;
-}
-
-.scraped-example:not(.expanded) .code-wrapper .example-wrap pre.rust {
+.scraped-example:not(.expanded) .code-wrapper pre {
overflow-y: hidden;
max-height: 240px;
padding-bottom: 0;
}
+.scraped-example:not(.expanded) .code-wrapper pre.line-numbers {
+ overflow-x: hidden;
+}
+
.scraped-example .code-wrapper .prev {
position: absolute;
top: 0.25em;
diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js
index 664b187e33e9..383ae001bc21 100644
--- a/src/librustdoc/html/static/js/scrape-examples.js
+++ b/src/librustdoc/html/static/js/scrape-examples.js
@@ -1,14 +1,28 @@
/* global addClass, hasClass, removeClass, onEach */
(function () {
- // Scroll code block to put the given code location in the middle of the viewer
+ // Number of lines shown when code viewer is not expanded
+ const MAX_LINES = 10;
+
+ // Scroll code block to the given code location
function scrollToLoc(elt, loc) {
- var wrapper = elt.querySelector(".code-wrapper");
- var halfHeight = wrapper.offsetHeight / 2;
var lines = elt.querySelector('.line-numbers');
- var offsetMid = (lines.children[loc[0]].offsetTop
- + lines.children[loc[1]].offsetTop) / 2;
- var scrollOffset = offsetMid - halfHeight;
+ var scrollOffset;
+
+ // If the block is greater than the size of the viewer,
+ // then scroll to the top of the block. Otherwise scroll
+ // to the middle of the block.
+ if (loc[1] - loc[0] > MAX_LINES) {
+ var line = Math.max(0, loc[0] - 1);
+ scrollOffset = lines.children[line].offsetTop;
+ } else {
+ var wrapper = elt.querySelector(".code-wrapper");
+ var halfHeight = wrapper.offsetHeight / 2;
+ var offsetMid = (lines.children[loc[0]].offsetTop
+ + lines.children[loc[1]].offsetTop) / 2;
+ scrollOffset = offsetMid - halfHeight;
+ }
+
lines.scrollTo(0, scrollOffset);
elt.querySelector(".rust").scrollTo(0, scrollOffset);
}