Auto merge of #79742 - GuillaumeGomez:move-tooltips-messages-out-of-html, r=Nemo157

Move tooltips messages out of html

First thing first: nothing in the output has changed. You still have the "i" on the left of code blocks examples when they have `ignore`, `compile_fail`, `should_panic` and `edition`. The behavior also remains the same: when you hover the "i", you have the corresponding message showing up.

So now, why this PR then? I realized recently that we were actually generating those messages into the HTML every time whereas all messages are the same (except for the edition ones, I'll come back to it later). So instead of generating more content, I simply moved it inside the CSS thanks to pseudo elements (`::before` and `::after`). The message is now inside `::after` and we use the `::before` to have the small triangle on the left of the message. So now, we have less HTML generated which is seems pretty nice.

So now, back to the `edition` change: the message is globally the same, but the "edition" itself can be different (2015 or 2018 currently, I expect 2021 to arrive not too far in the future). So the only difference for it is that I added a new attribute on the tooltip called `edition` which contains this information. Then, the `::after` uses it inside its `content` (you can get the content of an element's attribute by using `attr` and concat different strings by simply having them after the other).

Don't hesitate if a part of my explanations isn't clear.

r? `@jyn514`
This commit is contained in:
bors 2020-12-24 15:22:28 +00:00
commit b2516121e2
7 changed files with 52 additions and 71 deletions

View File

@ -11,6 +11,7 @@ use std::fmt::{Display, Write};
use std::iter::Peekable;
use rustc_lexer::{LiteralKind, TokenKind};
use rustc_span::edition::Edition;
use rustc_span::symbol::Ident;
use rustc_span::with_default_session_globals;
@ -19,16 +20,20 @@ crate fn render_with_highlighting(
src: String,
class: Option<&str>,
playground_button: Option<&str>,
tooltip: Option<(&str, &str)>,
tooltip: Option<(Option<Edition>, &str)>,
) -> String {
debug!("highlighting: ================\n{}\n==============", src);
let mut out = String::with_capacity(src.len());
if let Some((tooltip, class)) = tooltip {
if let Some((edition_info, class)) = tooltip {
write!(
out,
"<div class='information'><div class='tooltip {}'>ⓘ<span \
class='tooltiptext'>{}</span></div></div>",
class, tooltip
"<div class='information'><div class='tooltip {}'{}>ⓘ</div></div>",
class,
if let Some(edition_info) = edition_info {
format!(" data-edition=\"{}\"", edition_info)
} else {
String::new()
},
)
.unwrap();
}

View File

@ -284,60 +284,27 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
});
let tooltip = if ignore != Ignore::None {
Some(("This example is not tested".to_owned(), "ignore"))
Some((None, "ignore"))
} else if compile_fail {
Some(("This example deliberately fails to compile".to_owned(), "compile_fail"))
Some((None, "compile_fail"))
} else if should_panic {
Some(("This example panics".to_owned(), "should_panic"))
Some((None, "should_panic"))
} else if explicit_edition {
Some((format!("This code runs with edition {}", edition), "edition"))
Some((Some(edition), "edition"))
} else {
None
};
if let Some((s1, s2)) = tooltip {
s.push_str(&highlight::render_with_highlighting(
text,
Some(&format!(
"rust-example-rendered{}",
if ignore != Ignore::None {
" ignore"
} else if compile_fail {
" compile_fail"
} else if should_panic {
" should_panic"
} else if explicit_edition {
" edition "
} else {
""
}
)),
playground_button.as_deref(),
Some((s1.as_str(), s2)),
));
Some(Event::Html(s.into()))
} else {
s.push_str(&highlight::render_with_highlighting(
text,
Some(&format!(
"rust-example-rendered{}",
if ignore != Ignore::None {
" ignore"
} else if compile_fail {
" compile_fail"
} else if should_panic {
" should_panic"
} else if explicit_edition {
" edition "
} else {
""
}
)),
playground_button.as_deref(),
None,
));
Some(Event::Html(s.into()))
}
s.push_str(&highlight::render_with_highlighting(
text,
Some(&format!(
"rust-example-rendered{}",
if let Some((_, class)) = tooltip { format!(" {}", class) } else { String::new() }
)),
playground_button.as_deref(),
tooltip,
));
Some(Event::Html(s.into()))
}
}

View File

@ -1079,20 +1079,29 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
cursor: pointer;
}
.tooltip .tooltiptext {
width: 120px;
.tooltip::after {
display: none;
text-align: center;
padding: 5px 3px 3px 3px;
border-radius: 6px;
margin-left: 5px;
top: -5px;
left: 105%;
z-index: 10;
font-size: 16px;
}
.tooltip .tooltiptext::after {
.tooltip.ignore::after {
content: "This example is not tested";
}
.tooltip.compile_fail::after {
content: "This example deliberately fails to compile";
}
.tooltip.should_panic::after {
content: "This example panics";
}
.tooltip.edition::after {
content: "This code runs with edition " attr(data-edition);
}
.tooltip::before {
content: " ";
position: absolute;
top: 50%;
@ -1100,9 +1109,10 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
margin-top: -5px;
border-width: 5px;
border-style: solid;
display: none;
}
.tooltip:hover .tooltiptext {
.tooltip:hover::before, .tooltip:hover::after {
display: inline;
}

View File

@ -388,13 +388,13 @@ pre.ignore:hover, .information:hover + pre.ignore {
color: #39AFD7;
}
.tooltip .tooltiptext {
.tooltip::after {
background-color: #314559;
color: #c5c5c5;
border: 1px solid #5c6773;
}
.tooltip .tooltiptext::after {
.tooltip::before {
border-color: transparent #314559 transparent transparent;
}

View File

@ -337,13 +337,13 @@ pre.ignore:hover, .information:hover + pre.ignore {
color: #0089ff;
}
.tooltip .tooltiptext {
.tooltip::after {
background-color: #000;
color: #fff;
border-color: #000;
}
.tooltip .tooltiptext::after {
.tooltip::before {
border-color: transparent black transparent transparent;
}

View File

@ -329,12 +329,12 @@ pre.ignore:hover, .information:hover + pre.ignore {
color: #0089ff;
}
.tooltip .tooltiptext {
.tooltip::after {
background-color: #000;
color: #fff;
}
.tooltip .tooltiptext::after {
.tooltip::before {
border-color: transparent black transparent transparent;
}

View File

@ -1,10 +1,9 @@
#![crate_name = "foo"]
// ignore-tidy-linelength
// @has foo/fn.bar.html '//*[@class="tooltip compile_fail"]/span' "This example deliberately fails to compile"
// @has foo/fn.bar.html '//*[@class="tooltip ignore"]/span' "This example is not tested"
// @has foo/fn.bar.html '//*[@class="tooltip should_panic"]/span' "This example panics"
// @has foo/fn.bar.html '//*[@class="tooltip compile_fail"]' "ⓘ"
// @has foo/fn.bar.html '//*[@class="tooltip ignore"]' "ⓘ"
// @has foo/fn.bar.html '//*[@class="tooltip should_panic"]' "ⓘ"
// @has foo/fn.bar.html '//*[@data-edition="2018"]' "ⓘ"
/// foo
///
@ -20,7 +19,7 @@
/// hoo();
/// ```
///
/// ```
/// ```edition2018
/// let x = 0;
/// ```
pub fn bar() -> usize { 2 }