Rollup merge of #127474 - tesuji:foldable-inline-derefs, r=t-rustdoc

doc: Make block of inline Deref methods foldable

After:
![image](https://github.com/rust-lang/rust/assets/15225902/3e8ab320-dbf7-436f-9be0-d0ef82664663)
Before:
![image](https://github.com/rust-lang/rust/assets/15225902/f6f7635d-d4c3-437e-a2d9-147726287b05)

Fix  #127470.

Current status:
- [x] Bug when hovering over title "Methods from ...": The anchor sign $ overlaps with `[-]`: https://github.com/rust-lang/rust/pull/127474#issuecomment-2222930038
    => Fixed by https://github.com/rust-lang/rust/pull/127474#issuecomment-2228886292
This commit is contained in:
Matthias Krüger 2024-09-02 04:19:27 +02:00 committed by GitHub
commit c90991db17
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 63 additions and 4 deletions

View File

@ -1250,6 +1250,7 @@ fn render_assoc_items_inner(
let Some(v) = cache.impls.get(&it) else { return }; let Some(v) = cache.impls.get(&it) else { return };
let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none()); let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none());
if !non_trait.is_empty() { if !non_trait.is_empty() {
let mut close_tags = <Vec<&str>>::with_capacity(1);
let mut tmp_buf = Buffer::html(); let mut tmp_buf = Buffer::html();
let (render_mode, id, class_html) = match what { let (render_mode, id, class_html) = match what {
AssocItemRender::All => { AssocItemRender::All => {
@ -1260,6 +1261,8 @@ fn render_assoc_items_inner(
let id = let id =
cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx)))); cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
let derived_id = cx.derive_id(&id); let derived_id = cx.derive_id(&id);
tmp_buf.write_str("<details class=\"toggle big-toggle\" open><summary>");
close_tags.push("</details>");
write_impl_section_heading( write_impl_section_heading(
&mut tmp_buf, &mut tmp_buf,
&format!( &format!(
@ -1269,6 +1272,7 @@ fn render_assoc_items_inner(
), ),
&id, &id,
); );
tmp_buf.write_str("</summary>");
if let Some(def_id) = type_.def_id(cx.cache()) { if let Some(def_id) = type_.def_id(cx.cache()) {
cx.deref_id_map.insert(def_id, id); cx.deref_id_map.insert(def_id, id);
} }
@ -1302,6 +1306,9 @@ fn render_assoc_items_inner(
impls_buf.into_inner() impls_buf.into_inner()
) )
.unwrap(); .unwrap();
for tag in close_tags.into_iter().rev() {
w.write_str(tag).unwrap();
}
} }
} }
@ -1558,7 +1565,7 @@ fn render_impl(
let cache = &shared.cache; let cache = &shared.cache;
let traits = &cache.traits; let traits = &cache.traits;
let trait_ = i.trait_did().map(|did| &traits[&did]); let trait_ = i.trait_did().map(|did| &traits[&did]);
let mut close_tags = String::new(); let mut close_tags = <Vec<&str>>::with_capacity(2);
// For trait implementations, the `interesting` output contains all methods that have doc // 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 // comments, and the `boring` output contains all methods that do not. The distinction is
@ -1870,7 +1877,7 @@ fn render_default_items(
if render_mode == RenderMode::Normal { if render_mode == RenderMode::Normal {
let toggled = !(impl_items.is_empty() && default_impl_items.is_empty()); let toggled = !(impl_items.is_empty() && default_impl_items.is_empty());
if toggled { if toggled {
close_tags.insert_str(0, "</details>"); close_tags.push("</details>");
write!( write!(
w, w,
"<details class=\"toggle implementors-toggle\"{}>\ "<details class=\"toggle implementors-toggle\"{}>\
@ -1916,14 +1923,16 @@ fn render_default_items(
} }
if !default_impl_items.is_empty() || !impl_items.is_empty() { if !default_impl_items.is_empty() || !impl_items.is_empty() {
w.write_str("<div class=\"impl-items\">"); w.write_str("<div class=\"impl-items\">");
close_tags.insert_str(0, "</div>"); close_tags.push("</div>");
} }
} }
if !default_impl_items.is_empty() || !impl_items.is_empty() { if !default_impl_items.is_empty() || !impl_items.is_empty() {
w.push_buffer(default_impl_items); w.push_buffer(default_impl_items);
w.push_buffer(impl_items); w.push_buffer(impl_items);
} }
w.write_str(&close_tags); for tag in close_tags.into_iter().rev() {
w.write_str(tag);
}
} }
// Render the items that appear on the right side of methods, impls, and // Render the items that appear on the right side of methods, impls, and

View File

@ -1852,6 +1852,11 @@ details.toggle {
position: relative; position: relative;
} }
details.big-toggle {
/* This makes [-] on the same line as <summary>. */
contain: inline-size;
}
/* The hideme class is used on summary tags that contain a span with /* The hideme class is used on summary tags that contain a span with
placeholder text shown only when the toggle is closed. For instance, placeholder text shown only when the toggle is closed. For instance,
"Expand description" or "Show methods". */ "Expand description" or "Show methods". */
@ -1942,6 +1947,11 @@ details.toggle > summary:not(.hideme)::before {
left: -24px; left: -24px;
} }
details.big-toggle > summary:not(.hideme)::before {
left: -34px;
top: 9px;
}
/* When a "hideme" summary is open and the "Expand description" or "Show /* When a "hideme" summary is open and the "Expand description" or "Show
methods" text is hidden, we want the [-] toggle that remains to not methods" text is hidden, we want the [-] toggle that remains to not
affect the layout of the items to its right. To do that, we use affect the layout of the items to its right. To do that, we use

View File

@ -0,0 +1,30 @@
// This test ensures that several clickable items actually have the pointer cursor.
go-to: "file://" + |DOC_PATH| + "/lib2/struct.Derefer.html"
assert-text: (".big-toggle summary", "Methods from Deref<Target = str>§")
// We ensure it doesn't go over `§`.
assert-css: (".big-toggle summary::before", {
"left": "-34px",
"top": "9px",
})
// It should NOT have the same X or Y position as the other toggles.
compare-elements-position-false: (
".big-toggle summary::before",
".method-toggle summary::before",
["x", "y"],
)
// We now check that if we're in mobile mode, it gets back to its original X position.
set-window-size: (600, 600)
assert-css: (".big-toggle summary::before", {
"left": "-11px",
"top": "9px",
})
// It should have the same X position as the other toggles.
compare-elements-position: (".big-toggle summary::before", ".method-toggle summary::before", ["x"])
// But still shouldn't have the same Y position.
compare-elements-position-false: (
".big-toggle summary::before",
".method-toggle summary::before",
["y"],
)

View File

@ -356,3 +356,13 @@ pub trait TraitWithLongItemsName {
fn this_is_a_method_with_a_long_name_returning_something() -> String; fn this_is_a_method_with_a_long_name_returning_something() -> String;
} }
} }
pub struct Derefer(String);
impl std::ops::Deref for Derefer {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.0
}
}