Skip to content

Commit

Permalink
Unify scraped examples with other code examples
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Aug 30, 2024
1 parent 0d63418 commit 0d156f2
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 130 deletions.
33 changes: 9 additions & 24 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2445,28 +2445,6 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c
let needs_expansion = line_max - line_min > NUM_VISIBLE_LINES;
let locations_encoded = serde_json::to_string(&line_ranges).unwrap();

write!(
&mut w,
"<div class=\"scraped-example {expanded_cls}\" data-locs=\"{locations}\">\
<div class=\"scraped-example-title\">\
{name} (<a href=\"{url}\">{title}</a>)\
</div>\
<div class=\"code-wrapper\">",
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
// later by the JS for interactions.
locations = Escape(&locations_encoded)
)
.unwrap();

if line_ranges.len() > 1 {
w.write_str(r#"<button class="prev">&pr;</button> <button class="next">&sc;</button>"#)
.unwrap();
}

// Look for the example file in the source map if it exists, otherwise return a dummy span
let file_span = (|| {
let source_map = tcx.sess.source_map();
Expand Down Expand Up @@ -2497,9 +2475,16 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c
cx,
&cx.root_path(),
highlight::DecorationInfo(decoration_info),
sources::SourceContext::Embedded { offset: line_min, needs_expansion },
sources::SourceContext::Embedded(sources::ScrapedInfo {
needs_prev_next_buttons: line_ranges.len() > 1,
needs_expansion,
offset: line_min,
name: &call_data.display_name,
url: init_url,
title: init_title,
locations: locations_encoded,
}),
);
w.write_str("</div></div>").unwrap();

true
};
Expand Down
57 changes: 38 additions & 19 deletions src/librustdoc/html/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,34 @@ where
}
}

pub(crate) enum SourceContext {
pub(crate) struct ScrapedInfo<'a> {
pub(crate) offset: usize,
pub(crate) needs_prev_next_buttons: bool,
pub(crate) name: &'a str,
pub(crate) url: &'a str,
pub(crate) title: &'a str,
pub(crate) locations: String,
pub(crate) needs_expansion: bool,
}

#[derive(Template)]
#[template(path = "scraped_source.html")]
struct ScrapedSource<'a, Code: std::fmt::Display> {
info: ScrapedInfo<'a>,
lines: RangeInclusive<usize>,
code_html: Code,
}

#[derive(Template)]
#[template(path = "source.html")]
struct Source<Code: std::fmt::Display> {
lines: RangeInclusive<usize>,
code_html: Code,
}

pub(crate) enum SourceContext<'a> {
Standalone,
Embedded { offset: usize, needs_expansion: bool },
Embedded(ScrapedInfo<'a>),
}

/// Wrapper struct to render the source code of a file. This will do things like
Expand All @@ -303,23 +328,8 @@ pub(crate) fn print_src(
context: &Context<'_>,
root_path: &str,
decoration_info: highlight::DecorationInfo,
source_context: SourceContext,
source_context: SourceContext<'_>,
) {
#[derive(Template)]
#[template(path = "source.html")]
struct Source<Code: std::fmt::Display> {
embedded: bool,
needs_expansion: bool,
lines: RangeInclusive<usize>,
code_html: Code,
}
let lines = s.lines().count();
let (embedded, needs_expansion, lines) = match source_context {
SourceContext::Standalone => (false, false, 1..=lines),
SourceContext::Embedded { offset, needs_expansion } => {
(true, needs_expansion, (1 + offset)..=(lines + offset))
}
};
let current_href = context
.href_from_span(clean::Span::new(file_span), false)
.expect("only local crates should have sources emitted");
Expand All @@ -332,5 +342,14 @@ pub(crate) fn print_src(
);
Ok(())
});
Source { embedded, needs_expansion, lines, code_html: code }.render_into(&mut writer).unwrap();
let lines = s.lines().count();
match source_context {
SourceContext::Standalone => {
Source { lines: (1..=lines), code_html: code }.render_into(&mut writer).unwrap()
}
SourceContext::Embedded(info) => {
let lines = (1 + info.offset)..=(lines + info.offset);
ScrapedSource { info, lines, code_html: code }.render_into(&mut writer).unwrap();
}
};
}
4 changes: 4 additions & 0 deletions src/librustdoc/html/static/css/noscript.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ nav.sub {
--copy-path-button-color: #999;
--copy-path-img-filter: invert(50%);
--copy-path-img-hover-filter: invert(35%);
--code-example-button-color: #7f7f7f;
--code-example-button-hover-color: #595959;
--codeblock-error-hover-color: rgb(255, 0, 0);
--codeblock-error-color: rgba(255, 0, 0, .5);
--codeblock-ignore-hover-color: rgb(255, 142, 0);
Expand Down Expand Up @@ -162,6 +164,8 @@ nav.sub {
--copy-path-button-color: #999;
--copy-path-img-filter: invert(50%);
--copy-path-img-hover-filter: invert(65%);
--code-example-button-color: #7f7f7f;
--code-example-button-hover-color: #a5a5a5;
--codeblock-error-hover-color: rgb(255, 0, 0);
--codeblock-error-color: rgba(255, 0, 0, .5);
--codeblock-ignore-hover-color: rgb(255, 142, 0);
Expand Down
115 changes: 42 additions & 73 deletions src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -760,23 +760,38 @@ ul.block, .block li {
flex-grow: 1;
}

.rustdoc:not(.src) .example-wrap pre {
.scraped-example:not(.expanded) {
/* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number
* of lines shown in the un-expanded example code viewer. This pre needs to have
* a max-height equal to line-height * N. The line-height is currently 1.5em,
* and we include additional 10px for padding. */
max-height: calc(1.5em * 5 + 10px);
}

.rustdoc:not(.src) .scraped-example:not(.expanded) pre.src-line-numbers,
.rustdoc:not(.src) .scraped-example:not(.expanded) pre.rust {
padding-bottom: 0;
/* See above comment, should be the same max-height. */
max-height: calc(1.5em * 5 + 10px);
overflow: auto hidden;
}

.rustdoc:not(.src) .example-wrap pre {
overflow: auto;
}

.rustdoc .example-wrap pre.example-line-numbers,
.rustdoc .example-wrap pre.src-line-numbers {
flex-grow: 0;
min-width: fit-content; /* prevent collapsing into nothing in truncated scraped examples */
overflow: initial;
flex-grow: 0;
text-align: right;
-webkit-user-select: none;
user-select: none;
padding: 14px 8px;
color: var(--src-line-numbers-span-color);
}

.rustdoc .example-wrap pre.src-line-numbers {
.rustdoc .scraped-example pre.src-line-numbers {
padding: 14px 0;
}
.src-line-numbers a, .src-line-numbers span {
Expand Down Expand Up @@ -1488,17 +1503,23 @@ instead, we check that it's not a "finger" cursor.
.example-wrap .button-holder.keep-visible {
visibility: visible;
}
.example-wrap .button-holder .copy-button, .example-wrap .test-arrow {
.example-wrap .button-holder > * {
background: var(--main-background-color);
cursor: pointer;
border-radius: var(--button-border-radius);
height: var(--copy-path-height);
width: var(--copy-path-width);
border: 0;
color: var(--code-example-button-color);
}
.example-wrap .button-holder .copy-button {
.example-wrap .button-holder > *:hover {
color: var(--code-example-button-hover-color);
}
.example-wrap .button-holder > *:not(:first-child) {
margin-left: var(--button-left-margin);
}
.example-wrap .button-holder .copy-button {
padding: 2px 0 0 4px;
border: 0;
}
.example-wrap .button-holder .copy-button::before,
.example-wrap .test-arrow::before {
Expand Down Expand Up @@ -2334,99 +2355,41 @@ in src-script.js and main.js
color: var(--scrape-example-help-hover-color);
}

.scraped-example {
/* So .scraped-example-title can be positioned absolutely */
position: relative;
}

.scraped-example .code-wrapper {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
}

.scraped-example:not(.expanded) .code-wrapper {
/* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number
* of lines shown in the un-expanded example code viewer. This pre needs to have
* a max-height equal to line-height * N. The line-height is currently 1.5em,
* and we include additional 10px for padding. */
max-height: calc(1.5em * 5 + 10px);
}

.scraped-example:not(.expanded) .code-wrapper pre {
overflow-y: hidden;
padding-bottom: 0;
/* See above comment, should be the same max-height. */
max-height: calc(1.5em * 5 + 10px);
}

.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,
.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre {
/* See above comment, except this height is based on HIDDEN_MAX_LINES. */
max-height: calc(1.5em * 10 + 10px);
}

.scraped-example .code-wrapper .next,
.scraped-example .code-wrapper .prev,
.scraped-example .code-wrapper .expand {
color: var(--main-color);
position: absolute;
top: 0.25em;
z-index: 1;
padding: 0;
background: none;
border: none;
/* iOS button gradient: https://stackoverflow.com/q/5438567 */
-webkit-appearance: none;
opacity: 1;
}
.scraped-example .code-wrapper .prev {
right: 2.25em;
}
.scraped-example .code-wrapper .next {
right: 1.25em;
}
.scraped-example .code-wrapper .expand {
right: 0.25em;
}

.scraped-example:not(.expanded) .code-wrapper::before,
.scraped-example:not(.expanded) .code-wrapper::after {
.scraped-example:not(.expanded)::before,
.scraped-example:not(.expanded)::after {
content: " ";
width: 100%;
height: 5px;
position: absolute;
z-index: 1;
}
.scraped-example:not(.expanded) .code-wrapper::before {
.scraped-example:not(.expanded)::before {
top: 0;
background: linear-gradient(to bottom,
var(--scrape-example-code-wrapper-background-start),
var(--scrape-example-code-wrapper-background-end));
}
.scraped-example:not(.expanded) .code-wrapper::after {
.scraped-example:not(.expanded)::after {
bottom: 0;
background: linear-gradient(to top,
var(--scrape-example-code-wrapper-background-start),
var(--scrape-example-code-wrapper-background-end));
}

.scraped-example .code-wrapper .example-wrap {
.scraped-example:not(.expanded) {
width: 100%;
overflow-y: hidden;
margin-bottom: 0;
}

.scraped-example:not(.expanded) .code-wrapper .example-wrap {
.scraped-example:not(.expanded) {
overflow-x: hidden;
}

.scraped-example .example-wrap .rust span.highlight {
.scraped-example .rust span.highlight {
background: var(--scrape-example-code-line-highlight);
}
.scraped-example .example-wrap .rust span.highlight.focus {
.scraped-example .rust span.highlight.focus {
background: var(--scrape-example-code-line-highlight-focus);
}

Expand Down Expand Up @@ -2520,6 +2483,8 @@ by default.
--copy-path-button-color: #999;
--copy-path-img-filter: invert(50%);
--copy-path-img-hover-filter: invert(35%);
--code-example-button-color: #7f7f7f;
--code-example-button-hover-color: #595959;
--codeblock-error-hover-color: rgb(255, 0, 0);
--codeblock-error-color: rgba(255, 0, 0, .5);
--codeblock-ignore-hover-color: rgb(255, 142, 0);
Expand Down Expand Up @@ -2622,6 +2587,8 @@ by default.
--copy-path-button-color: #999;
--copy-path-img-filter: invert(50%);
--copy-path-img-hover-filter: invert(65%);
--code-example-button-color: #7f7f7f;
--code-example-button-hover-color: #a5a5a5;
--codeblock-error-hover-color: rgb(255, 0, 0);
--codeblock-error-color: rgba(255, 0, 0, .5);
--codeblock-ignore-hover-color: rgb(255, 142, 0);
Expand Down Expand Up @@ -2731,6 +2698,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
--copy-path-button-color: #fff;
--copy-path-img-filter: invert(70%);
--copy-path-img-hover-filter: invert(100%);
--code-example-button-color: #b2b2b2;
--code-example-button-hover-color: #fff;
--codeblock-error-hover-color: rgb(255, 0, 0);
--codeblock-error-color: rgba(255, 0, 0, .5);
--codeblock-ignore-hover-color: rgb(255, 142, 0);
Expand Down
9 changes: 7 additions & 2 deletions src/librustdoc/html/static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1855,8 +1855,13 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
// Since the button will be added, no need to keep this listener around.
elem.removeEventListener("mouseover", addCopyButton);

const parent = document.createElement("div");
parent.className = "button-holder";
// If this is a scrapped example, there will already be a "button-holder" element.
let parent = elem.querySelector(".button-holder");
if (!parent) {
parent = document.createElement("div");
parent.className = "button-holder";
}

const runButton = elem.querySelector(".test-arrow");
if (runButton !== null) {
// If there is a run button, we move it into the same div.
Expand Down
3 changes: 1 addition & 2 deletions src/librustdoc/html/static/js/scrape-examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
const line = Math.max(0, loc[0] - 1);
scrollOffset = lines.children[line].offsetTop;
} else {
const wrapper = elt.querySelector(".code-wrapper");
const halfHeight = wrapper.offsetHeight / 2;
const halfHeight = elt.offsetHeight / 2;
const offsetTop = lines.children[loc[0]].offsetTop;
const lastLine = lines.children[loc[1]];
const offsetBot = lastLine.offsetTop + lastLine.offsetHeight;
Expand Down
Loading

0 comments on commit 0d156f2

Please sign in to comment.