Migrate trait and impl blocks' toggles into

This commit is contained in:
Guillaume Gomez 2021-04-28 21:19:52 +02:00
parent bcd696d722
commit dfde867fcd
7 changed files with 124 additions and 185 deletions

View file

@ -625,10 +625,6 @@ impl ItemKind {
| KeywordItem(_) => [].iter(),
}
}
crate fn is_type_alias(&self) -> bool {
matches!(self, ItemKind::TypedefItem(..) | ItemKind::AssocTypeItem(..))
}
}
#[derive(Clone, Debug)]

View file

@ -508,23 +508,16 @@ fn document(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, parent: Option
if let Some(ref name) = item.name {
info!("Documenting {}", name);
}
document_item_info(w, cx, item, false, parent);
document_full(w, item, cx, false);
document_item_info(w, cx, item, parent);
document_full(w, item, cx);
}
/// Render md_text as markdown.
fn render_markdown(
w: &mut Buffer,
cx: &Context<'_>,
md_text: &str,
links: Vec<RenderedLink>,
is_hidden: bool,
) {
fn render_markdown(w: &mut Buffer, cx: &Context<'_>, md_text: &str, links: Vec<RenderedLink>) {
let mut ids = cx.id_map.borrow_mut();
write!(
w,
"<div class=\"docblock{}\">{}</div>",
if is_hidden { " hidden" } else { "" },
"<div class=\"docblock\">{}</div>",
Markdown(
md_text,
&links,
@ -544,11 +537,10 @@ fn document_short(
item: &clean::Item,
cx: &Context<'_>,
link: AssocItemLink<'_>,
is_hidden: bool,
parent: &clean::Item,
show_def_docs: bool,
) {
document_item_info(w, cx, item, is_hidden, Some(parent));
document_item_info(w, cx, item, Some(parent));
if !show_def_docs {
return;
}
@ -565,19 +557,14 @@ fn document_short(
}
}
write!(
w,
"<div class='docblock{}'>{}</div>",
if is_hidden { " hidden" } else { "" },
summary_html,
);
write!(w, "<div class='docblock'>{}</div>", summary_html,);
}
}
fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context<'_>, is_hidden: bool) {
fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context<'_>) {
if let Some(s) = cx.shared.maybe_collapsed_doc_value(item) {
debug!("Doc block: =====\n{}\n=====", s);
render_markdown(w, cx, &s, item.links(cx), is_hidden);
render_markdown(w, cx, &s, item.links(cx));
}
}
@ -590,16 +577,11 @@ fn document_item_info(
w: &mut Buffer,
cx: &Context<'_>,
item: &clean::Item,
is_hidden: bool,
parent: Option<&clean::Item>,
) {
let item_infos = short_item_info(item, cx, parent);
if !item_infos.is_empty() {
if is_hidden {
w.write_str("<div class=\"item-info hidden\">");
} else {
w.write_str("<div class=\"item-info\">");
}
w.write_str("<div class=\"item-info\">");
for info in item_infos {
w.write_str(&info);
}
@ -1281,8 +1263,12 @@ fn render_impl(
let trait_ = i.trait_did_full(cache).map(|did| &traits[&did]);
let mut close_tags = String::new();
// For trait implementations, the `interesting` output contains all methods that have doc
// comments, and the `boring` output contains all methods that do not. The distinction is
// used to allow hiding the boring methods.
fn doc_impl_item(
w: &mut Buffer,
boring: &mut Buffer,
interesting: &mut Buffer,
cx: &Context<'_>,
item: &clean::Item,
parent: &clean::Item,
@ -1305,15 +1291,46 @@ fn render_impl(
}
};
let (is_hidden, extra_class) =
if (trait_.is_none() || item.doc_value().is_some() || item.kind.is_type_alias())
&& !is_default_item
{
(false, "")
} else {
(true, " hidden")
};
let in_trait_class = if trait_.is_some() { " trait-impl" } else { "" };
let mut doc_buffer = Buffer::empty_from(boring);
let mut info_buffer = Buffer::empty_from(boring);
let mut short_documented = true;
if render_method_item {
if !is_default_item {
if let Some(t) = trait_ {
// The trait item may have been stripped so we might not
// find any documentation or stability for it.
if let Some(it) = t.items.iter().find(|i| i.name == item.name) {
// We need the stability of the item from the trait
// because impls can't have a stability.
if item.doc_value().is_some() {
document_item_info(&mut info_buffer, cx, it, Some(parent));
document_full(&mut doc_buffer, item, cx);
short_documented = false;
} else {
// In case the item isn't documented,
// provide short documentation from the trait.
document_short(&mut doc_buffer, it, cx, link, parent, show_def_docs);
}
}
} else {
document_item_info(&mut info_buffer, cx, item, Some(parent));
if show_def_docs {
document_full(&mut doc_buffer, item, cx);
short_documented = false;
}
}
} else {
document_short(&mut doc_buffer, item, cx, link, parent, show_def_docs);
}
}
let w = if short_documented && trait_.is_some() { interesting } else { boring };
if !doc_buffer.is_empty() {
w.write_str("<details class=\"rustdoc-toggle\" open><summary>");
}
match *item.kind {
clean::MethodItem(..) | clean::TyMethodItem(_) => {
// Only render when the method is not static or we allow static methods
@ -1326,11 +1343,7 @@ fn render_impl(
})
})
.map(|item| format!("{}.{}", item.type_(), name));
write!(
w,
"<h4 id=\"{}\" class=\"{}{}{}\">",
id, item_type, extra_class, in_trait_class,
);
write!(w, "<h4 id=\"{}\" class=\"{}{}\">", id, item_type, in_trait_class,);
w.write_str("<code>");
render_assoc_item(
w,
@ -1355,11 +1368,7 @@ fn render_impl(
clean::TypedefItem(ref tydef, _) => {
let source_id = format!("{}.{}", ItemType::AssocType, name);
let id = cx.derive_id(source_id.clone());
write!(
w,
"<h4 id=\"{}\" class=\"{}{}{}\"><code>",
id, item_type, extra_class, in_trait_class
);
write!(w, "<h4 id=\"{}\" class=\"{}{}\"><code>", id, item_type, in_trait_class);
assoc_type(
w,
item,
@ -1376,11 +1385,7 @@ fn render_impl(
clean::AssocConstItem(ref ty, ref default) => {
let source_id = format!("{}.{}", item_type, name);
let id = cx.derive_id(source_id.clone());
write!(
w,
"<h4 id=\"{}\" class=\"{}{}{}\"><code>",
id, item_type, extra_class, in_trait_class
);
write!(w, "<h4 id=\"{}\" class=\"{}{}\"><code>", id, item_type, in_trait_class);
assoc_const(
w,
item,
@ -1405,11 +1410,7 @@ fn render_impl(
clean::AssocTypeItem(ref bounds, ref default) => {
let source_id = format!("{}.{}", item_type, name);
let id = cx.derive_id(source_id.clone());
write!(
w,
"<h4 id=\"{}\" class=\"{}{}{}\"><code>",
id, item_type, extra_class, in_trait_class
);
write!(w, "<h4 id=\"{}\" class=\"{}{}\"><code>", id, item_type, in_trait_class);
assoc_type(
w,
item,
@ -1427,38 +1428,20 @@ fn render_impl(
_ => panic!("can't make docs for trait item with name {:?}", item.name),
}
if render_method_item {
if !is_default_item {
if let Some(t) = trait_ {
// The trait item may have been stripped so we might not
// find any documentation or stability for it.
if let Some(it) = t.items.iter().find(|i| i.name == item.name) {
// We need the stability of the item from the trait
// because impls can't have a stability.
if item.doc_value().is_some() {
document_item_info(w, cx, it, is_hidden, Some(parent));
document_full(w, item, cx, is_hidden);
} else {
// In case the item isn't documented,
// provide short documentation from the trait.
document_short(w, it, cx, link, is_hidden, parent, show_def_docs);
}
}
} else {
document_item_info(w, cx, item, is_hidden, Some(parent));
if show_def_docs {
document_full(w, item, cx, is_hidden);
}
}
} else {
document_short(w, item, cx, link, is_hidden, parent, show_def_docs);
}
w.push_buffer(info_buffer);
if !doc_buffer.is_empty() {
w.write_str("</summary>");
w.push_buffer(doc_buffer);
w.push_str("</details>");
}
}
let mut impl_items = Buffer::empty_from(w);
let mut default_impl_items = Buffer::empty_from(w);
for trait_item in &i.inner_impl().items {
doc_impl_item(
&mut default_impl_items,
&mut impl_items,
cx,
trait_item,
@ -1475,6 +1458,7 @@ fn render_impl(
fn render_default_items(
w: &mut Buffer,
tmp_w: &mut Buffer,
cx: &Context<'_>,
t: &clean::Trait,
i: &clean::Impl,
@ -1494,6 +1478,7 @@ fn render_impl(
doc_impl_item(
w,
tmp_w,
cx,
trait_item,
parent,
@ -1515,6 +1500,7 @@ fn render_impl(
if show_default_items {
if let Some(t) = trait_ {
render_default_items(
&mut default_impl_items,
&mut impl_items,
cx,
&t.trait_,
@ -1527,7 +1513,7 @@ fn render_impl(
);
}
}
let details_str = if impl_items.is_empty() {
let details_str = if impl_items.is_empty() && default_impl_items.is_empty() {
""
} else {
"<details class=\"rustdoc-toggle implementors-toggle\" open><summary>"
@ -1554,7 +1540,7 @@ fn render_impl(
"{}<h3 id=\"{}\" class=\"impl\"{}><code class=\"in-band\">",
details_str, id, aliases
);
if !impl_items.is_empty() {
if !impl_items.is_empty() || !default_impl_items.is_empty() {
close_tags.insert_str(0, "</details>");
}
write!(w, "{}", i.inner_impl().print(use_absolute, cx));
@ -1585,7 +1571,7 @@ fn render_impl(
aliases,
i.inner_impl().print(false, cx)
);
if !impl_items.is_empty() {
if !impl_items.is_empty() || !default_impl_items.is_empty() {
close_tags.insert_str(0, "</details>");
}
}
@ -1598,7 +1584,7 @@ fn render_impl(
outer_const_version,
);
write_srclink(cx, &i.impl_item, w);
if impl_items.is_empty() {
if impl_items.is_empty() && default_impl_items.is_empty() {
w.write_str("</h3>");
} else {
w.write_str("</h3></summary>");
@ -1627,8 +1613,13 @@ fn render_impl(
);
}
}
if !impl_items.is_empty() {
if !impl_items.is_empty() || !default_impl_items.is_empty() {
w.write_str("<div class=\"impl-items\">");
w.push_buffer(default_impl_items);
if trait_.is_some() && !impl_items.is_empty() {
w.write_str("<details class=\"undocumented\"><summary></summary>");
close_tags.insert_str(0, "</details>");
}
w.push_buffer(impl_items);
close_tags.insert_str(0, "</div>");
}

View file

@ -1156,8 +1156,6 @@ function hideThemeButtonState() {
var hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true";
var hideImplementors = getSettingValue("auto-collapse-implementors") !== "false";
var hideLargeItemContents = getSettingValue("auto-hide-large-items") !== "false";
var hideTraitImplementations =
getSettingValue("auto-hide-trait-implementations") !== "false";
var impl_list = document.getElementById("trait-implementations-list");
if (impl_list !== null) {
@ -1173,39 +1171,18 @@ function hideThemeButtonState() {
});
}
var func = function(e) {
var next = e.nextElementSibling;
if (next && hasClass(next, "item-info")) {
next = next.nextElementSibling;
}
if (!next) {
return;
}
if (hasClass(next, "docblock")) {
var newToggle = toggle.cloneNode(true);
insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
if (hideMethodDocs === true && hasClass(e, "method") === true) {
collapseDocs(newToggle, "hide");
if (hideMethodDocs === true) {
onEachLazy(document.getElementsByClassName("method"), function(e) {
var toggle = e.parentNode;
if (toggle) {
toggle = toggle.parentNode;
}
}
};
if (toggle && toggle.tagName === "DETAILS") {
toggle.open = false;
}
});
}
var funcImpl = function(e) {
var next = e.nextElementSibling;
if (next && hasClass(next, "item-info")) {
next = next.nextElementSibling;
}
if (next && hasClass(next, "docblock")) {
next = next.nextElementSibling;
}
if (!next) {
return;
}
};
onEachLazy(document.getElementsByClassName("method"), func);
onEachLazy(document.getElementsByClassName("associatedconstant"), func);
var impl_call = function() {};
onEachLazy(document.getElementsByTagName("details"), function (e) {
var showLargeItem = !hideLargeItemContents && hasClass(e, "type-contents-toggle");
var showImplementor = !hideImplementors && hasClass(e, "implementors-toggle");
@ -1213,60 +1190,6 @@ function hideThemeButtonState() {
e.open = true;
}
});
if (hideMethodDocs === true) {
impl_call = function(e, newToggle) {
if (e.id.match(/^impl(?:-\d+)?$/) === null) {
// Automatically minimize all non-inherent impls
if (hasClass(e, "impl") === true) {
collapseDocs(newToggle, "hide");
}
}
};
}
var newToggle = document.createElement("a");
newToggle.href = "javascript:void(0)";
newToggle.className = "collapse-toggle hidden-default collapsed";
newToggle.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
"</span>] Show hidden undocumented items";
function toggleClicked() {
if (hasClass(this, "collapsed")) {
removeClass(this, "collapsed");
onEachLazy(this.parentNode.getElementsByClassName("hidden"), function(x) {
if (hasClass(x, "content") === false) {
removeClass(x, "hidden");
addClass(x, "x");
}
}, true);
this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(false) +
"</span>] Hide undocumented items";
} else {
addClass(this, "collapsed");
onEachLazy(this.parentNode.getElementsByClassName("x"), function(x) {
if (hasClass(x, "content") === false) {
addClass(x, "hidden");
removeClass(x, "x");
}
}, true);
this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
"</span>] Show hidden undocumented items";
}
}
onEachLazy(document.getElementsByClassName("impl-items"), function(e) {
onEachLazy(e.getElementsByClassName("associatedconstant"), func);
// We transform the DOM iterator into a vec of DOM elements to prevent performance
// issues on webkit browsers.
var hiddenElems = Array.prototype.slice.call(e.getElementsByClassName("hidden"));
var needToggle = hiddenElems.some(function(hiddenElem) {
return hasClass(hiddenElem, "content") === false &&
hasClass(hiddenElem, "docblock") === false;
});
if (needToggle === true) {
var inner_toggle = newToggle.cloneNode(true);
inner_toggle.onclick = toggleClicked;
e.insertBefore(inner_toggle, e.firstChild);
impl_call(e.previousSibling, inner_toggle);
}
});
var currentType = document.getElementsByClassName("type-decl")[0];
var className = null;

View file

@ -147,6 +147,9 @@ h1, h2, h3, h4,
.sidebar, a.source, .search-input, .content table td:first-child > a,
.collapse-toggle, div.item-list .out-of-band,
#source-sidebar, #sidebar-toggle,
details.rustdoc-toggle > summary::before,
details.undocumented > summary::before,
.content ul.crate a.crate,
/* This selector is for the items listed in the "all items" page. */
#main > ul.docblock > li > a {
font-family: "Fira Sans", Arial, sans-serif;
@ -154,7 +157,6 @@ h1, h2, h3, h4,
.content ul.crate a.crate {
font-size: 16px/1.6;
font-family: "Fira Sans", Arial, sans-serif;
}
ol, ul {
@ -596,7 +598,9 @@ h4 > code, h3 > code, .invisible > code {
left: -19px;
}
.content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant {
.content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant,
.content .impl-items details > summary > .type,
.impl-items details > summary > .associatedconstant {
margin-left: 20px;
}
@ -1764,7 +1768,10 @@ details.rustdoc-toggle > summary.hideme {
cursor: pointer;
}
details.rustdoc-toggle > summary::-webkit-details-marker {
details.rustdoc-toggle > summary::-webkit-details-marker,
details.rustdoc-toggle > summary::marker,
details.undocumented > summary::-webkit-details-marker,
details.undocumented > summary::marker {
display: none;
}
@ -1787,6 +1794,14 @@ details.rustdoc-toggle > summary.hideme::before {
details.rustdoc-toggle > summary:not(.hideme)::before {
position: absolute;
left: -23px;
top: initial;
}
.impl-items > details.rustdoc-toggle > summary:not(.hideme)::before,
.undocumented > details.rustdoc-toggle > summary:not(.hideme)::before {
position: absolute;
top: 3px;
left: -2px;
}
/* When a "hideme" summary is open and the "Expand description" or "Show
@ -1798,7 +1813,7 @@ details.rustdoc-toggle[open] > summary.hideme {
position: absolute;
}
details.rustdoc-toggle[open] {
details.rustdoc-toggle, details.undocumented {
position: relative;
}
@ -1810,3 +1825,14 @@ details.rustdoc-toggle[open] > summary::before {
content: "[]";
display: inline;
}
details.undocumented > summary::before {
content: "[+] Show hidden undocumented items";
cursor: pointer;
font-size: 16px;
font-weight: 300;
}
details.undocumented[open] > summary::before {
content: "[-] Hide undocumented items";
}

View file

@ -226,7 +226,8 @@ a {
.collapse-toggle,
details.rustdoc-toggle > summary.hideme > span,
details.rustdoc-toggle > summary::before {
details.rustdoc-toggle > summary::before,
details.undocumented > summary::before {
color: #999;
}

View file

@ -188,7 +188,8 @@ a.test-arrow {
.collapse-toggle,
details.rustdoc-toggle > summary.hideme > span,
details.rustdoc-toggle > summary::before {
details.rustdoc-toggle > summary::before,
details.undocumented > summary::before {
color: #999;
}

View file

@ -186,7 +186,8 @@ a.test-arrow {
.collapse-toggle,
details.rustdoc-toggle > summary.hideme > span,
details.rustdoc-toggle > summary::before {
details.rustdoc-toggle > summary::before,
details.undocumented > summary::before {
color: #999;
}