parent
8e0cac18cd
commit
303653ef65
@ -107,10 +107,6 @@ pub(crate) fn into_inner(self) -> String {
|
||||
self.buffer
|
||||
}
|
||||
|
||||
pub(crate) fn insert_str(&mut self, idx: usize, s: &str) {
|
||||
self.buffer.insert_str(idx, s);
|
||||
}
|
||||
|
||||
pub(crate) fn push_str(&mut self, s: &str) {
|
||||
self.buffer.push_str(s);
|
||||
}
|
||||
|
@ -69,11 +69,13 @@ pub(crate) struct Context<'tcx> {
|
||||
/// the source files are present in the html rendering, then this will be
|
||||
/// `true`.
|
||||
pub(crate) include_sources: bool,
|
||||
/// Collection of all types with notable traits referenced in the current module.
|
||||
pub(crate) types_with_notable_traits: FxHashSet<clean::Type>,
|
||||
}
|
||||
|
||||
// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
|
||||
#[cfg(all(not(windows), target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
rustc_data_structures::static_assert_size!(Context<'_>, 128);
|
||||
rustc_data_structures::static_assert_size!(Context<'_>, 160);
|
||||
|
||||
/// Shared mutable state used in [`Context`] and elsewhere.
|
||||
pub(crate) struct SharedContext<'tcx> {
|
||||
@ -532,6 +534,7 @@ fn init(
|
||||
deref_id_map: FxHashMap::default(),
|
||||
shared: Rc::new(scx),
|
||||
include_sources,
|
||||
types_with_notable_traits: FxHashSet::default(),
|
||||
};
|
||||
|
||||
if emit_crate {
|
||||
@ -560,6 +563,7 @@ fn make_child_renderer(&self) -> Self {
|
||||
id_map: IdMap::new(),
|
||||
shared: Rc::clone(&self.shared),
|
||||
include_sources: self.include_sources,
|
||||
types_with_notable_traits: FxHashSet::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -803,6 +807,7 @@ fn item(&mut self, item: clean::Item) -> Result<(), Error> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
||||
symbol::{sym, Symbol},
|
||||
BytePos, FileName, RealFileName,
|
||||
};
|
||||
use serde::ser::SerializeSeq;
|
||||
use serde::ser::{SerializeMap, SerializeSeq};
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use crate::clean::{self, ItemId, RenderedLink, SelfTy};
|
||||
@ -803,7 +803,7 @@ fn assoc_method(
|
||||
d: &clean::FnDecl,
|
||||
link: AssocItemLink<'_>,
|
||||
parent: ItemType,
|
||||
cx: &Context<'_>,
|
||||
cx: &mut Context<'_>,
|
||||
render_mode: RenderMode,
|
||||
) {
|
||||
let tcx = cx.tcx();
|
||||
@ -836,6 +836,8 @@ fn assoc_method(
|
||||
+ name.as_str().len()
|
||||
+ generics_len;
|
||||
|
||||
let notable_traits = d.output.as_return().and_then(|output| notable_traits_button(output, cx));
|
||||
|
||||
let (indent, indent_str, end_newline) = if parent == ItemType::Trait {
|
||||
header_len += 4;
|
||||
let indent_str = " ";
|
||||
@ -861,13 +863,9 @@ fn assoc_method(
|
||||
name = name,
|
||||
generics = g.print(cx),
|
||||
decl = d.full_print(header_len, indent, cx),
|
||||
notable_traits = d
|
||||
.output
|
||||
.as_return()
|
||||
.and_then(|output| notable_traits_decl(output, cx))
|
||||
.unwrap_or_default(),
|
||||
notable_traits = notable_traits.unwrap_or_default(),
|
||||
where_clause = print_where_clause(g, cx, indent, end_newline),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/// Writes a span containing the versions at which an item became stable and/or const-stable. For
|
||||
@ -967,7 +965,7 @@ fn render_assoc_item(
|
||||
item: &clean::Item,
|
||||
link: AssocItemLink<'_>,
|
||||
parent: ItemType,
|
||||
cx: &Context<'_>,
|
||||
cx: &mut Context<'_>,
|
||||
render_mode: RenderMode,
|
||||
) {
|
||||
match &*item.kind {
|
||||
@ -1277,8 +1275,8 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
|
||||
}
|
||||
}
|
||||
|
||||
fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> Option<String> {
|
||||
let mut out = Buffer::html();
|
||||
pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &mut Context<'_>) -> Option<String> {
|
||||
let mut has_notable_trait = false;
|
||||
|
||||
let did = ty.def_id(cx.cache())?;
|
||||
|
||||
@ -1291,6 +1289,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> Option<String> {
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(impls) = cx.cache().impls.get(&did) {
|
||||
for i in impls {
|
||||
let impl_ = i.inner_impl();
|
||||
@ -1304,56 +1303,106 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> Option<String> {
|
||||
|
||||
if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable_trait(cx.tcx()))
|
||||
{
|
||||
if out.is_empty() {
|
||||
write!(
|
||||
&mut out,
|
||||
"<span class=\"notable\">Notable traits for {}</span>\
|
||||
<code class=\"content\">",
|
||||
impl_.for_.print(cx)
|
||||
);
|
||||
}
|
||||
|
||||
//use the "where" class here to make it small
|
||||
write!(
|
||||
&mut out,
|
||||
"<span class=\"where fmt-newline\">{}</span>",
|
||||
impl_.print(false, cx)
|
||||
);
|
||||
for it in &impl_.items {
|
||||
if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
|
||||
out.push_str("<span class=\"where fmt-newline\"> ");
|
||||
let empty_set = FxHashSet::default();
|
||||
let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set);
|
||||
assoc_type(
|
||||
&mut out,
|
||||
it,
|
||||
&tydef.generics,
|
||||
&[], // intentionally leaving out bounds
|
||||
Some(&tydef.type_),
|
||||
src_link,
|
||||
0,
|
||||
cx,
|
||||
);
|
||||
out.push_str(";</span>");
|
||||
}
|
||||
}
|
||||
has_notable_trait = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if has_notable_trait {
|
||||
cx.types_with_notable_traits.insert(ty.clone());
|
||||
Some(format!(
|
||||
"<span class=\"notable-traits\" data-ty=\"{ty:#}\">\
|
||||
<span class=\"notable-traits-tooltip\">ⓘ</span>\
|
||||
</span>",
|
||||
ty = ty.print(cx),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
|
||||
let mut out = Buffer::html();
|
||||
|
||||
let did = ty.def_id(cx.cache()).expect("notable_traits_button already checked this");
|
||||
|
||||
let impls = cx.cache().impls.get(&did).expect("notable_traits_button already checked this");
|
||||
|
||||
for i in impls {
|
||||
let impl_ = i.inner_impl();
|
||||
if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache()) {
|
||||
// Two different types might have the same did,
|
||||
// without actually being the same.
|
||||
continue;
|
||||
}
|
||||
if let Some(trait_) = &impl_.trait_ {
|
||||
let trait_did = trait_.def_id();
|
||||
|
||||
if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable_trait(cx.tcx())) {
|
||||
if out.is_empty() {
|
||||
write!(
|
||||
&mut out,
|
||||
"<h3 class=\"notable\">Notable traits for <code>{}</code></h3>\
|
||||
<pre class=\"content\"><code>",
|
||||
impl_.for_.print(cx)
|
||||
);
|
||||
}
|
||||
|
||||
//use the "where" class here to make it small
|
||||
write!(
|
||||
&mut out,
|
||||
"<span class=\"where fmt-newline\">{}</span>",
|
||||
impl_.print(false, cx)
|
||||
);
|
||||
for it in &impl_.items {
|
||||
if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
|
||||
out.push_str("<span class=\"where fmt-newline\"> ");
|
||||
let empty_set = FxHashSet::default();
|
||||
let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set);
|
||||
assoc_type(
|
||||
&mut out,
|
||||
it,
|
||||
&tydef.generics,
|
||||
&[], // intentionally leaving out bounds
|
||||
Some(&tydef.type_),
|
||||
src_link,
|
||||
0,
|
||||
cx,
|
||||
);
|
||||
out.push_str(";</span>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if out.is_empty() {
|
||||
return None;
|
||||
write!(&mut out, "</code></pre>",);
|
||||
}
|
||||
|
||||
out.insert_str(
|
||||
0,
|
||||
"<span class=\"notable-traits\"><span class=\"notable-traits-tooltip\">ⓘ\
|
||||
<span class=\"notable-traits-tooltiptext\"><span class=\"docblock\">",
|
||||
);
|
||||
out.push_str("</code></span></span></span></span>");
|
||||
(format!("{:#}", ty.print(cx)), out.into_inner())
|
||||
}
|
||||
|
||||
Some(out.into_inner())
|
||||
pub(crate) fn notable_traits_json<'a>(
|
||||
tys: impl Iterator<Item = &'a clean::Type>,
|
||||
cx: &Context<'_>,
|
||||
) -> String {
|
||||
let mp: Vec<(String, String)> = tys.map(|ty| notable_traits_decl(ty, cx)).collect();
|
||||
struct NotableTraitsMap(Vec<(String, String)>);
|
||||
impl Serialize for NotableTraitsMap {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut map = serializer.serialize_map(Some(self.0.len()))?;
|
||||
for item in &self.0 {
|
||||
map.serialize_entry(&item.0, &item.1)?;
|
||||
}
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
serde_json::to_string(&NotableTraitsMap(mp))
|
||||
.expect("serialize (string, string) -> json object cannot fail")
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -17,9 +17,10 @@
|
||||
|
||||
use super::{
|
||||
collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference,
|
||||
item_ty_to_section, notable_traits_decl, render_all_impls, render_assoc_item,
|
||||
render_assoc_items, render_attributes_in_code, render_attributes_in_pre, render_impl,
|
||||
render_rightside, render_stability_since_raw, AssocItemLink, Context, ImplRenderingParameters,
|
||||
item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls,
|
||||
render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre,
|
||||
render_impl, render_rightside, render_stability_since_raw, AssocItemLink, Context,
|
||||
ImplRenderingParameters,
|
||||
};
|
||||
use crate::clean;
|
||||
use crate::config::ModuleSorting;
|
||||
@ -183,6 +184,16 @@ pub(super) fn print_item(
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
// Render notable-traits.js used for all methods in this module.
|
||||
if !cx.types_with_notable_traits.is_empty() {
|
||||
write!(
|
||||
buf,
|
||||
r#"<script type="text/json" id="notable-traits-data">{}</script>"#,
|
||||
notable_traits_json(cx.types_with_notable_traits.iter(), cx)
|
||||
);
|
||||
cx.types_with_notable_traits.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// For large structs, enums, unions, etc, determine whether to hide their fields
|
||||
@ -516,6 +527,9 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
|
||||
+ name.as_str().len()
|
||||
+ generics_len;
|
||||
|
||||
let notable_traits =
|
||||
f.decl.output.as_return().and_then(|output| notable_traits_button(output, cx));
|
||||
|
||||
wrap_into_item_decl(w, |w| {
|
||||
wrap_item(w, "fn", |w| {
|
||||
render_attributes_in_pre(w, it, "");
|
||||
@ -533,16 +547,11 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
|
||||
generics = f.generics.print(cx),
|
||||
where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline),
|
||||
decl = f.decl.full_print(header_len, 0, cx),
|
||||
notable_traits = f
|
||||
.decl
|
||||
.output
|
||||
.as_return()
|
||||
.and_then(|output| notable_traits_decl(output, cx))
|
||||
.unwrap_or_default(),
|
||||
notable_traits = notable_traits.unwrap_or_default(),
|
||||
);
|
||||
});
|
||||
});
|
||||
document(w, cx, it, None, HeadingOffset::H2)
|
||||
document(w, cx, it, None, HeadingOffset::H2);
|
||||
}
|
||||
|
||||
fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Trait) {
|
||||
|
@ -22,3 +22,9 @@ nav.sub {
|
||||
.source .sidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.notable-traits {
|
||||
/* layout requires javascript
|
||||
https://github.com/rust-lang/rust/issues/102576 */
|
||||
display: none;
|
||||
}
|
||||
|
@ -183,6 +183,8 @@ h4.code-header {
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
/* position notable traits in mobile mode within the header */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#crate-search,
|
||||
@ -1268,13 +1270,12 @@ h3.variant {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.notable-traits:hover .notable-traits-tooltiptext,
|
||||
.notable-traits .notable-traits-tooltiptext.force-tooltip {
|
||||
.notable-traits .notable-traits-tooltiptext {
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.notable-traits .notable-traits-tooltiptext {
|
||||
display: none;
|
||||
.notable-traits-tooltiptext {
|
||||
padding: 5px 3px 3px 3px;
|
||||
border-radius: 6px;
|
||||
margin-left: 5px;
|
||||
@ -1292,22 +1293,26 @@ h3.variant {
|
||||
content: "\00a0\00a0\00a0";
|
||||
}
|
||||
|
||||
.notable-traits .docblock {
|
||||
.notable-traits-tooltiptext .docblock {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.notable-traits .notable {
|
||||
margin: 0;
|
||||
margin-bottom: 13px;
|
||||
.notable-traits-tooltiptext .notable {
|
||||
font-size: 1.1875rem;
|
||||
font-weight: 600;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.notable-traits .docblock code.content {
|
||||
.notable-traits-tooltiptext pre, .notable-traits-tooltiptext code {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.notable-traits-tooltiptext .docblock pre.content {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 1.25rem;
|
||||
white-space: pre-wrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.search-failed {
|
||||
|
@ -790,6 +790,19 @@ function loadCss(cssUrl) {
|
||||
// we need to switch away from mobile mode and make the main content area scrollable.
|
||||
hideSidebar();
|
||||
}
|
||||
if (window.CURRENT_NOTABLE_ELEMENT) {
|
||||
// As a workaround to the behavior of `contains: layout` used in doc togglers, the
|
||||
// notable traits popup is positioned using javascript.
|
||||
//
|
||||
// This means when the window is resized, we need to redo the layout.
|
||||
const base = window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE;
|
||||
const force_visible = base.NOTABLE_FORCE_VISIBLE;
|
||||
hideNotable();
|
||||
if (force_visible) {
|
||||
showNotable(base);
|
||||
base.NOTABLE_FORCE_VISIBLE = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function handleClick(id, f) {
|
||||
@ -822,10 +835,78 @@ function loadCss(cssUrl) {
|
||||
});
|
||||
});
|
||||
|
||||
function showNotable(e) {
|
||||
if (!window.NOTABLE_TRAITS) {
|
||||
const data = document.getElementById("notable-traits-data");
|
||||
if (data) {
|
||||
window.NOTABLE_TRAITS = JSON.parse(data.innerText);
|
||||
} else {
|
||||
throw new Error("showNotable() called on page without any notable traits!");
|
||||
}
|
||||
}
|
||||
if (window.CURRENT_NOTABLE_ELEMENT && window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE === e) {
|
||||
// Make this function idempotent.
|
||||
return;
|
||||
}
|
||||
hideNotable();
|
||||
const ty = e.getAttribute("data-ty");
|
||||
const tooltip = e.getElementsByClassName("notable-traits-tooltip")[0];
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.innerHTML = "<div class=\"docblock\">" + window.NOTABLE_TRAITS[ty] + "</div>";
|
||||
wrapper.className = "notable-traits-tooltiptext";
|
||||
tooltip.appendChild(wrapper);
|
||||
const pos = wrapper.getBoundingClientRect();
|
||||
tooltip.removeChild(wrapper);
|
||||
wrapper.style.top = (pos.top + window.scrollY) + "px";
|
||||
wrapper.style.left = (pos.left + window.scrollX) + "px";
|
||||
wrapper.style.width = pos.width + "px";
|
||||
document.documentElement.appendChild(wrapper);
|
||||
window.CURRENT_NOTABLE_ELEMENT = wrapper;
|
||||
window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE = e;
|
||||
wrapper.onpointerleave = function(ev) {
|
||||
// If this is a synthetic touch event, ignore it. A click event will be along shortly.
|
||||
if (ev.pointerType !== "mouse") {
|
||||
return;
|
||||
}
|
||||
if (!e.NOTABLE_FORCE_VISIBLE && !elemIsInParent(event.relatedTarget, e)) {
|
||||
hideNotable();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function hideNotable() {
|
||||
if (window.CURRENT_NOTABLE_ELEMENT) {
|
||||
window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false;
|
||||
document.documentElement.removeChild(window.CURRENT_NOTABLE_ELEMENT);
|
||||
window.CURRENT_NOTABLE_ELEMENT = null;
|
||||
}
|
||||
}
|
||||
|
||||
onEachLazy(document.getElementsByClassName("notable-traits"), e => {
|
||||
e.onclick = function() {
|
||||
this.getElementsByClassName("notable-traits-tooltiptext")[0]
|
||||
.classList.toggle("force-tooltip");
|
||||
this.NOTABLE_FORCE_VISIBLE = this.NOTABLE_FORCE_VISIBLE ? false : true;
|
||||
if (window.CURRENT_NOTABLE_ELEMENT && !this.NOTABLE_FORCE_VISIBLE) {
|
||||
hideNotable();
|
||||
} else {
|
||||
showNotable(this);
|
||||
}
|
||||
};
|
||||
e.onpointerenter = function(ev) {
|
||||
// If this is a synthetic touch event, ignore it. A click event will be along shortly.
|
||||
if (ev.pointerType !== "mouse") {
|
||||
return;
|
||||
}
|
||||
showNotable(this);
|
||||
};
|
||||
e.onpointerleave = function(ev) {
|
||||
// If this is a synthetic touch event, ignore it. A click event will be along shortly.
|
||||
if (ev.pointerType !== "mouse") {
|
||||
return;
|
||||
}
|
||||
if (!this.NOTABLE_FORCE_VISIBLE &&
|
||||
!elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT)) {
|
||||
hideNotable();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -25,22 +25,28 @@ assert-position: (
|
||||
{"x": 951},
|
||||
)
|
||||
// The tooltip should be beside the `i`
|
||||
// Also, clicking the tooltip should bring its text into the DOM
|
||||
assert-count: ("//*[@class='notable-traits-tooltiptext']", 0)
|
||||
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
|
||||
assert-count: ("//*[@class='notable-traits-tooltiptext']", 1)
|
||||
compare-elements-position-near: (
|
||||
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
|
||||
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
|
||||
"//*[@class='notable-traits-tooltiptext']",
|
||||
{"y": 2}
|
||||
)
|
||||
compare-elements-position-false: (
|
||||
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
|
||||
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
|
||||
"//*[@class='notable-traits-tooltiptext']",
|
||||
("x")
|
||||
)
|
||||
// The docblock should be flush with the border.
|
||||
assert-css: (
|
||||
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']/*[@class='docblock']",
|
||||
"//*[@class='notable-traits-tooltiptext']/*[@class='docblock']",
|
||||
{"margin-left": "0px"}
|
||||
)
|
||||
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
|
||||
move-cursor-to: "//h1"
|
||||
assert-count: ("//*[@class='notable-traits-tooltiptext']", 0)
|
||||
|
||||
// Now only the `i` should be on the next line.
|
||||
size: (1055, 600)
|
||||
@ -98,26 +104,31 @@ assert-position: (
|
||||
{"x": 289},
|
||||
)
|
||||
// The tooltip should be below `i`
|
||||
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
|
||||
assert-count: ("//*[@class='notable-traits-tooltiptext']", 1)
|
||||
compare-elements-position-near-false: (
|
||||
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
|
||||
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
|
||||
"//*[@class='notable-traits-tooltiptext']",
|
||||
{"y": 2}
|
||||
)
|
||||
compare-elements-position-false: (
|
||||
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
|
||||
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
|
||||
"//*[@class='notable-traits-tooltiptext']",
|
||||
("x")
|
||||
)
|
||||
compare-elements-position-near: (
|
||||
"//*[@id='method.create_an_iterator_from_read']/parent::*",
|
||||
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
|
||||
{"x": 5}
|
||||
"//*[@id='method.create_an_iterator_from_read']",
|
||||
"//*[@class='notable-traits-tooltiptext']",
|
||||
{"x": 10}
|
||||
)
|
||||
// The docblock should be flush with the border.
|
||||
assert-css: (
|
||||
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']/*[@class='docblock']",
|
||||
"//*[@class='notable-traits-tooltiptext']/*[@class='docblock']",
|
||||
{"margin-left": "0px"}
|
||||
)
|
||||
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
|
||||
move-cursor-to: "//h1"
|
||||
assert-count: ("//*[@class='notable-traits-tooltiptext']", 0)
|
||||
|
||||
// Checking on very small mobile. The `i` should be on its own line.
|
||||
size: (365, 600)
|
||||
|
@ -0,0 +1 @@
|
||||
<script type="text/json" id="notable-traits-data">{"&'static [SomeStruct]":"<h3 class=\"notable\">Notable traits for <code>&amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait_slice::SomeTrait\">SomeTrait</a> for &amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</span>"}</script>
|
@ -8,13 +8,13 @@ pub trait SomeTrait {}
|
||||
impl SomeTrait for &[SomeStruct] {}
|
||||
|
||||
// @has doc_notable_trait_slice/fn.bare_fn_matches.html
|
||||
// @has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]'
|
||||
// @snapshot bare_fn_matches - '//script[@id="notable-traits-data"]'
|
||||
pub fn bare_fn_matches() -> &'static [SomeStruct] {
|
||||
&[]
|
||||
}
|
||||
|
||||
// @has doc_notable_trait_slice/fn.bare_fn_no_matches.html
|
||||
// @!has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]'
|
||||
// @count - '//script[@id="notable-traits-data"]' 0
|
||||
pub fn bare_fn_no_matches() -> &'static [OtherStruct] {
|
||||
&[]
|
||||
}
|
||||
|
1
src/test/rustdoc/doc-notable_trait.bare-fn.html
Normal file
1
src/test/rustdoc/doc-notable_trait.bare-fn.html
Normal file
@ -0,0 +1 @@
|
||||
<script type="text/json" id="notable-traits-data">{"SomeStruct":"<h3 class=\"notable\">Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></span>"}</script>
|
@ -9,7 +9,8 @@ impl<T: SomeTrait> SomeTrait for Wrapper<T> {}
|
||||
#[doc(notable_trait)]
|
||||
pub trait SomeTrait {
|
||||
// @has doc_notable_trait/trait.SomeTrait.html
|
||||
// @has - '//code[@class="content"]' 'impl<T: SomeTrait> SomeTrait for Wrapper<T>'
|
||||
// @has - '//span[@class="notable-traits"]/@data-ty' 'Wrapper<Self>'
|
||||
// @snapshot wrap-me - '//script[@id="notable-traits-data"]'
|
||||
fn wrap_me(self) -> Wrapper<Self> where Self: Sized {
|
||||
Wrapper {
|
||||
inner: self,
|
||||
@ -22,15 +23,16 @@ impl SomeTrait for SomeStruct {}
|
||||
|
||||
impl SomeStruct {
|
||||
// @has doc_notable_trait/struct.SomeStruct.html
|
||||
// @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct'
|
||||
// @has - '//code[@class="content"]' 'impl<T: SomeTrait> SomeTrait for Wrapper<T>'
|
||||
// @has - '//span[@class="notable-traits"]/@data-ty' 'SomeStruct'
|
||||
// @snapshot some-struct-new - '//script[@id="notable-traits-data"]'
|
||||
pub fn new() -> SomeStruct {
|
||||
SomeStruct
|
||||
}
|
||||
}
|
||||
|
||||
// @has doc_notable_trait/fn.bare_fn.html
|
||||
// @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct'
|
||||
// @has - '//span[@class="notable-traits"]/@data-ty' 'SomeStruct'
|
||||
// @snapshot bare-fn - '//script[@id="notable-traits-data"]'
|
||||
pub fn bare_fn() -> SomeStruct {
|
||||
SomeStruct
|
||||
}
|
||||
|
1
src/test/rustdoc/doc-notable_trait.some-struct-new.html
Normal file
1
src/test/rustdoc/doc-notable_trait.some-struct-new.html
Normal file
@ -0,0 +1 @@
|
||||
<script type="text/json" id="notable-traits-data">{"Wrapper<Self>":"<h3 class=\"notable\">Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl&lt;T:&nbsp;<a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</span>","SomeStruct":"<h3 class=\"notable\">Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></span>"}</script>
|
1
src/test/rustdoc/doc-notable_trait.wrap-me.html
Normal file
1
src/test/rustdoc/doc-notable_trait.wrap-me.html
Normal file
@ -0,0 +1 @@
|
||||
<script type="text/json" id="notable-traits-data">{"Wrapper<Self>":"<h3 class=\"notable\">Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl&lt;T:&nbsp;<a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</span>"}</script>
|
1
src/test/rustdoc/spotlight-from-dependency.odd.html
Normal file
1
src/test/rustdoc/spotlight-from-dependency.odd.html
Normal file
@ -0,0 +1 @@
|
||||
<script type="text/json" id="notable-traits-data">{"Odd":"<h3 class=\"notable\">Notable traits for <code><a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html\" title=\"trait core::iter::traits::iterator::Iterator\">Iterator</a> for <a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></span><span class=\"where fmt-newline\"> type <a href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item\" class=\"associatedtype\">Item</a> = <a class=\"primitive\" href=\"{{channel}}/std/primitive.usize.html\">usize</a>;</span>"}</script>
|
@ -3,7 +3,8 @@
|
||||
use std::iter::Iterator;
|
||||
|
||||
// @has foo/struct.Odd.html
|
||||
// @has - '//*[@id="method.new"]//span[@class="notable-traits"]//code/span' 'impl Iterator for Odd'
|
||||
// @has - '//*[@id="method.new"]//span[@class="notable-traits"]/@data-ty' 'Odd'
|
||||
// @snapshot odd - '//script[@id="notable-traits-data"]'
|
||||
pub struct Odd {
|
||||
current: usize,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user