about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWill Crichton <wcrichto@cs.stanford.edu>2021-10-07 09:46:18 -0700
committerWill Crichton <wcrichto@cs.stanford.edu>2021-10-07 09:46:23 -0700
commitbb383edb69e2aaa718dc94147275053005d112e3 (patch)
tree1020f3b981ef933b301e5b932ea3bc051d9f1a48
parent5584c795975e9cc07884b479c7cb7aef2f47c231 (diff)
downloadrust-bb383edb69e2aaa718dc94147275053005d112e3.tar.gz
rust-bb383edb69e2aaa718dc94147275053005d112e3.zip
Move some expansion logic into generation-time, fix section header links, remove ID from line numbers, fix horizontal scrolling on non-expanded elements
-rw-r--r--src/librustdoc/html/render/mod.rs51
-rw-r--r--src/librustdoc/html/sources.rs19
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css12
-rw-r--r--src/librustdoc/html/static/js/scrape-examples.js12
4 files changed, 54 insertions, 40 deletions
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index d5e8d8b4906..5e4b068cf15 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2461,6 +2461,7 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
 }
 
 const MAX_FULL_EXAMPLES: usize = 5;
+const NUM_VISIBLE_LINES: usize = 10;
 
 /// Generates the HTML for example call locations generated via the --scrape-examples flag.
 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:
         w,
         "<div class=\"docblock scraped-example-list\">\
           <span></span>
-          <h5 id=\"scraped-examples\" class=\"section-header\">\
-             <a href=\"#{}\">Examples found in repository</a>\
+          <h5 id=\"{id}\" class=\"section-header\">\
+             <a href=\"#{id}\">Examples found in repository</a>\
           </h5>",
-        id
+        id = id
     );
 
     // 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:
         assert!(!call_data.locations.is_empty());
         let min_loc =
             call_data.locations.iter().min_by_key(|loc| loc.enclosing_item.byte_span.0).unwrap();
-        let (byte_offset, _) = min_loc.enclosing_item.byte_span;
-        let (line_offset, _) = min_loc.enclosing_item.line_span;
-        let byte_ceiling =
-            call_data.locations.iter().map(|loc| loc.enclosing_item.byte_span.1).max().unwrap();
+        let byte_min = min_loc.enclosing_item.byte_span.0;
+        let line_min = min_loc.enclosing_item.line_span.0;
+        let max_loc =
+            call_data.locations.iter().max_by_key(|loc| loc.enclosing_item.byte_span.1).unwrap();
+        let byte_max = max_loc.enclosing_item.byte_span.1;
+        let line_max = max_loc.enclosing_item.line_span.1;
 
         // The output code is limited to that byte range.
-        let contents_subset = &contents[(byte_offset as usize)..(byte_ceiling as usize)];
+        let contents_subset = &contents[(byte_min as usize)..(byte_max as usize)];
 
         // 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_offset` 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
             .locations
             .iter()
             .map(|loc| {
                 let (byte_lo, byte_hi) = loc.call_expr.byte_span;
                 let (line_lo, line_hi) = loc.call_expr.line_span;
-                (
-                    (byte_lo - byte_offset, byte_hi - byte_offset),
-                    (line_lo - line_offset, line_hi - line_offset),
-                )
+                ((byte_lo - byte_min, byte_hi - byte_min), (line_lo - line_min, line_hi - line_min))
             })
             .unzip();
 
         let (init_min, init_max) = line_ranges[0];
         let line_range = if init_min == init_max {
-            format!("line {}", init_min + line_offset + 1)
+            format!("line {}", init_min + line_min + 1)
         } else {
-            format!("lines {}-{}", init_min + line_offset + 1, init_max + line_offset + 1)
+            format!("lines {}-{}", init_min + line_min + 1, init_max + line_min + 1)
         };
 
+        let needs_expansion = line_max - line_min > NUM_VISIBLE_LINES;
+
         write!(
             w,
-            "<div class=\"scraped-example\" data-locs=\"{locations}\" data-offset=\"{offset}\">\
+            "<div class=\"scraped-example {expanded_cls}\" data-locs=\"{locations}\">\
                 <div class=\"scraped-example-title\">\
-                   {name} (<a href=\"{root}{url}\" target=\"_blank\">{line_range}</a>)\
+                   {name} (<a href=\"{root}{url}\">{line_range}</a>)\
                 </div>\
                 <div class=\"code-wrapper\">",
             root = cx.root_path(),
             url = call_data.url,
             name = call_data.display_name,
             line_range = line_range,
-            offset = line_offset,
+            expanded_cls = if needs_expansion { "" } else { "expanded" },
             // The locations are encoded as a data attribute, so they can be read
             // later by the JS for interactions.
             locations = serde_json::to_string(&line_ranges).unwrap(),
         );
         write!(w, r#"<span class="prev">&pr;</span> <span class="next">&sc;</span>"#);
-        write!(w, r#"<span class="expand">&varr;</span>"#);
+
+        if needs_expansion {
+            write!(w, r#"<span class="expand">&varr;</span>"#);
+        }
 
         // Look for the example file in the source map if it exists, otherwise return a dummy span
         let file_span = (|| {
@@ -2565,8 +2570,8 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
                 _ => false,
             })?;
             Some(rustc_span::Span::with_root_ctxt(
-                file.start_pos + BytePos(byte_offset),
-                file.start_pos + BytePos(byte_ceiling),
+                file.start_pos + BytePos(byte_min),
+                file.start_pos + BytePos(byte_max),
             ))
         })()
         .unwrap_or(rustc_span::DUMMY_SP);
@@ -2584,8 +2589,8 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
             file_span,
             cx,
             &root_path,
-            Some(line_offset),
             Some(highlight::DecorationInfo(decoration_info)),
+            sources::SourceContext::Embedded { offset: line_min },
         );
         write!(w, "</div></div>");
 
@@ -2648,7 +2653,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, def_id: DefId, item:
             it.for_each(|(_, call_data)| {
                 write!(
                     w,
-                    r#"<li><a href="{root}{url}" target="_blank">{name}</a></li>"#,
+                    r#"<li><a href="{root}{url}">{name}</a></li>"#,
                     root = cx.root_path(),
                     url = call_data.url,
                     name = call_data.display_name
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index c3441036d50..ffefc5450cd 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -212,7 +212,7 @@ impl SourceCollector<'_, 'tcx> {
                     &self.cx,
                     &root_path,
                     None,
-                    None,
+                    SourceContext::Standalone,
                 )
             },
             &self.cx.shared.style_files,
@@ -250,6 +250,11 @@ where
     }
 }
 
+crate enum SourceContext {
+    Standalone,
+    Embedded { offset: usize },
+}
+
 /// Wrapper struct to render the source code of a file. This will do things like
 /// adding line numbers to the left-hand side.
 crate fn print_src(
@@ -259,8 +264,8 @@ crate fn print_src(
     file_span: rustc_span::Span,
     context: &Context<'_>,
     root_path: &str,
-    offset: Option<usize>,
     decoration_info: Option<highlight::DecorationInfo>,
+    source_context: SourceContext,
 ) {
     let lines = s.lines().count();
     let mut line_numbers = Buffer::empty_from(buf);
@@ -271,9 +276,15 @@ crate fn print_src(
         tmp /= 10;
     }
     line_numbers.write_str("<pre class=\"line-numbers\">");
-    let offset = offset.unwrap_or(0);
     for i in 1..=lines {
-        writeln!(line_numbers, "<span id=\"{0}\">{0:1$}</span>", i + offset, cols);
+        match source_context {
+            SourceContext::Standalone => {
+                writeln!(line_numbers, "<span id=\"{0}\">{0:1$}</span>", i, cols)
+            }
+            SourceContext::Embedded { offset } => {
+                writeln!(line_numbers, "<span>{0:1$}</span>", i + offset, cols)
+            }
+        }
     }
     line_numbers.write_str("</pre>");
     highlight::render_with_highlighting(
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 7ebeffe85dd..820f6a00f20 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1978,12 +1978,16 @@ details.undocumented[open] > summary::before {
 	font-family: 'Fira Sans';
 }
 
-.scraped-example:not(.expanded) .code-wrapper pre.line-numbers,
-.scraped-example:not(.expanded) .code-wrapper .example-wrap pre.rust {
+.scraped-example:not(.expanded) .code-wrapper pre.line-numbers {
 	overflow: hidden;
 	max-height: 240px;
 }
 
+.scraped-example:not(.expanded) .code-wrapper .example-wrap pre.rust {
+	overflow-y: hidden;
+	max-height: 240px;
+}
+
 .scraped-example .code-wrapper .prev {
 	position: absolute;
 	top: 0.25em;
@@ -2019,7 +2023,7 @@ details.undocumented[open] > summary::before {
 .scraped-example:not(.expanded) .code-wrapper:before {
 	content: " ";
 	width: 100%;
-	height: 10px;
+	height: 5px;
 	position: absolute;
 	z-index: 100;
 	top: 0;
@@ -2029,7 +2033,7 @@ details.undocumented[open] > summary::before {
 .scraped-example:not(.expanded) .code-wrapper:after {
 	content: " ";
 	width: 100%;
-	height: 10px;
+	height: 5px;
 	position: absolute;
 	z-index: 100;
 	bottom: 0;
diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js
index 191ce37d653..307843f2426 100644
--- a/src/librustdoc/html/static/js/scrape-examples.js
+++ b/src/librustdoc/html/static/js/scrape-examples.js
@@ -15,7 +15,8 @@
 
     function updateScrapedExample(example) {
         var locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
-        var offset = parseInt(example.attributes.getNamedItem("data-offset").textContent);
+        var first_line_no = example.querySelector('.line-numbers > span:first-child');
+        var offset = parseInt(first_line_no.innerHTML) - 1;
 
         var locIndex = 0;
         var highlights = example.querySelectorAll('.highlight');
@@ -68,11 +69,8 @@
             example.querySelector('.next').remove();
         }
 
-        var codeEl = example.querySelector('.rust');
-        var codeOverflows = codeEl.scrollHeight > codeEl.clientHeight;
         var expandButton = example.querySelector('.expand');
-        if (codeOverflows) {
-            // If file is larger than default height, give option to expand the viewer
+        if (expandButton) {
             expandButton.addEventListener('click', function () {
                 if (hasClass(example, "expanded")) {
                     removeClass(example, "expanded");
@@ -81,10 +79,6 @@
                     addClass(example, "expanded");
                 }
             });
-        } else {
-            // Otherwise remove expansion buttons
-            addClass(example, 'expanded');
-            expandButton.remove();
         }
 
         // Start with the first example in view