Commit Graph

264 Commits

Author SHA1 Message Date
Matthias Krüger
e1da72c6e8
Rollup merge of #120736 - notriddle:notriddle/toc, r=t-rustdoc
rustdoc: add header map to the table of contents

## Summary

Add header sections to the sidebar TOC.

### Preview

![image](https://github.com/user-attachments/assets/eae4df02-86aa-4df4-8c61-a95685cd8829)

* http://notriddle.com/rustdoc-html-demo-9/toc/rust/std/index.html
* http://notriddle.com/rustdoc-html-demo-9/toc/rust-derive-builder/derive_builder/index.html

## Motivation

Some pages are very wordy, like these.

| crate | word count |
|--|--|
| [std::option](https://doc.rust-lang.org/stable/std/option/index.html) | 2,138
| [derive_builder](https://docs.rs/derive_builder/0.13.0/derive_builder/index.html) | 2,403
| [tracing](https://docs.rs/tracing/0.1.40/tracing/index.html) | 3,912
| [regex](https://docs.rs/regex/1.10.3/regex/index.html) | 8,412

This kind of very long document is more navigable with a table of contents, like Wikipedia's or the one [GitHub recently added](https://github.blog/changelog/2021-04-13-table-of-contents-support-in-markdown-files/) for READMEs.

In fact, the use case is so compelling, that it's been requested multiple times and implemented in an extension:

* https://github.com/rust-lang/rust/issues/80858
* https://github.com/rust-lang/rust/issues/28056
* https://github.com/rust-lang/rust/issues/14475
* https://rust.extension.sh/#show-table-of-content

(Some of these issues ask for more than this, so don’t close them.)

It's also been implemented by hand in some crates, because the author really thought it was needed. Protip: for a more exhaustive list, run [`site:docs.rs table of contents`](https://duckduckgo.com/?t=ffab&q=site%3Adocs.rs+table+of+contents&ia=web), though some of them are false positives.

* https://docs.rs/figment/0.10.14/figment/index.html#table-of-contents
* https://docs.rs/csv/1.3.0/csv/tutorial/index.html#table-of-contents
* https://docs.rs/axum/0.7.4/axum/response/index.html#table-of-contents
* https://docs.rs/regex-automata/0.4.5/regex_automata/index.html#table-of-contents

Unfortunately for these hand-built ToCs, because they're just part of the docs, there's no consistent way to turn them off if the reader doesn't want them. It's also more complicated to ensure they stay in sync with the docs they're supposed to describe, and they don't stay with you when you scroll like Wikipedia's [does now](https://uxdesign.cc/design-notes-on-the-2023-wikipedia-redesign-d6573b9af28d).

## Guide-level explanation

When writing docs for a top-level item, the first and second level of headers will be shown in an outline in the sidebar. In this context, "top level" means "not associated".

This means, if you're writing very long guides or explanations, and you want it to have a table of contents in the sidebar for its headings, the ideal place to attach it is usually the *module* or *crate*, because this page has fewer other things on it (and is the ideal place to describe "cross-cutting concerns" for its child items).

If you're reading documentation, and want to get rid of the table of contents, open the ![image](https://github.com/rust-lang/rust/assets/1593513/2ad82466-5fe3-4684-b1c2-6be4c99a8666) Settings panel and checkmark "Hide table of contents."

## Reference-level explanation

Top-level items have an outline generated. This works for potentially-malformed header trees by pairing a header with the nearest header with a higher level. For example:

```markdown
## A
# B
# C
## D
## E
```

A, B, and C are all siblings, and D and E are children of C.

Rustdoc only presents two layers of tree, but it tracks up to the full depth of 6 while preparing it.

That means that these two doc comment both generate the same outline:

```rust
/// # First
/// ## Second
struct One;
/// ## First
/// ### Second
struct Two;
```

## Drawbacks

The biggest drawback is adding more stuff to the sidebar.

My crawl through docs.rs shows this to, surprisingly, be less of a problem than I thought. The manually-built tables of contents, and the pages with dozens of headers, usually seem to be modules or crates, not types (where extreme scrolling would become a problem, since they already have methods to deal with).

The best example of a type with many headers is [vec::Vec](https://doc.rust-lang.org/1.75.0/std/vec/struct.Vec.html), which still only has five headers, not dozens like [axum::extract](https://docs.rs/axum/0.7.4/axum/extract/index.html).

## Rationale and alternatives

### Why in the existing sidebar?

The method links and the top-doc header links have more in common with each other than either of them do with the "In [parent module]" links, and should go together.

### Why limited to two levels?

The sidebar is pretty narrow, and I don't want too much space used by indentation. Making the sidebar wider, while it has some upsides, also takes up more space on middling-sized screens or tiled WMs.

### Why not line wrap?

That behaves strangely when resizing.

## Prior art

### Doc generators that have TOC for headers

https://hexdocs.pm/phoenix/Phoenix.Controller.html is very close, in the sense that it also has header sections directly alongside functions and types.

Another example, referenced as part of the [early sidebar discussion](https://github.com/rust-lang/rust/issues/37856) that added methods, Ruby will show a table of contents in the sidebar (for example, on the [ARGF](https://docs.ruby-lang.org/en/master/ARGF.html) class). According to their changelog, [they added it in 2013](06137bde8c/History.rdoc (400--2013-02-24-)).

Haskell seems to mix text and functions even more freely than Elixir. For example, this [Naming conventions](https://hackage.haskell.org/package/base-4.19.0.0/docs/Control-Monad.html#g:3) is plain text, and is immediately followed by functions. And the [Pandoc top level](https://hackage.haskell.org/package/pandoc-3.1.11.1/docs/Text-Pandoc.html) has items split up by function, rather than by kind. Their TOC matches exactly with the contents of the page.

### Doc generators that don't have header TOC, but still have headers

Elm, interestingly enough, seems to have the same setup that Rust used to have: sibling navigation between modules, and no index within a single page. [They keep Haskell's habit of named sections with machine-generated type signatures](https://package.elm-lang.org/packages/elm/browser/latest/Browser-Dom), though.

[PHP](https://www.php.net/manual/en/book.datetime.php), like elm, also has a right-hand sidebar with sibling navigation. However, PHP has a single page for a single method, unlike Rust's page for an entire "class." So even though these pages have headers, it's never more than ten at most. And when they have guides, those guides are also multi-page.

## Unresolved questions

* Writing recommendations for anyone who wants to take advantage of this.
* Right now, it does not line wrap. That might be a bad idea: a lot of these are getting truncated.
* Split sidebars, which I [tried implementing](https://rust-lang.zulipchat.com/#narrow/stream/266220-t-rustdoc/topic/Table.20of.20contents), are not required. The TOC can be turned off, if it's really a problem. Implemented in https://github.com/rust-lang/rust/pull/120818, but needs more, separate, discussion.

## Future possibilities

I would like to do a better job of distinguishing global navigation from local navigation. Rustdoc has a pretty reasonable information architecture, if only we did a better job of communicating it.

This PR aims, mostly, to help doc authors help their users by writing docs that can be more effectively skimmed. But it doesn't do anything to make it easier to tell the TOC and the Module Nav apart.
2024-09-05 03:47:40 +02:00
Matthias Krüger
c90991db17
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
2024-09-02 04:19:27 +02:00
Michael Howell
bead042d5e rustdoc: add test case for modnav position when TOC is off 2024-08-20 16:54:04 -07:00
Michael Howell
12a3c42ccc rustdoc: consistentify #TOC and #ModNav to lowercase 2024-08-20 16:51:40 -07:00
Michael Howell
a7aea5d96b Add configuration options to hide TOC or module navigation 2024-08-20 16:27:42 -07:00
Michael Howell
1aebff96ad Add Top TOC support to rustdoc
This commit adds the headers for the top level documentation to
rustdoc's existing table of contents, along with associated items.

It only show two levels of headers. Going further would require the
sidebar to be wider, and that seems unnecessary (the crates that
have manually-built TOCs usually don't need deeply nested headers).
2024-08-20 16:27:42 -07:00
Michael Howell
9d7574f9b0 rustdoc: animate the :target highlight
This approach is, roughly, based on how Discourse does it.
It came up while discussing some other possible sidebar changes,
as a design that made rapid scanning easier while avoiding the
inherent trade-offs in summarizing.
2024-08-19 18:14:35 -07:00
Guillaume Gomez
c6e3385d95
Rollup merge of #128394 - GuillaumeGomez:run-button, r=t-rustdoc
Unify run button display with "copy code" button and with mdbook buttons

Follow-up of https://github.com/rust-lang/rust/pull/128339.

It looks like this (coherency++, yeay!):

![Screenshot from 2024-07-30 15-16-31](https://github.com/user-attachments/assets/5e262e5b-f338-4085-94ca-e223033a43db)

Can be tested [here](https://rustdoc.crud.net/imperio/run-button/foo/struct.Bar.html).

r? `@notriddle`
2024-08-12 17:09:15 +02:00
Michael Howell
3a183256ad rustdoc-search: account for numeric disambiguators on impls
Fixes #128676
2024-08-06 07:36:12 -07:00
Guillaume Gomez
59cb15946d Prevent clicking on a link or on a button to toggle the code example buttons visibility 2024-08-05 11:05:40 +02:00
Guillaume Gomez
be71bd9cec Update GUI tests for code example buttons 2024-08-05 11:04:51 +02:00
Matthias Krüger
c2b085b4d4
Rollup merge of #128339 - GuillaumeGomez:click-code-example, r=notriddle
[rustdoc] Make the buttons remain when code example is clicked

Follow-up of https://github.com/rust-lang/rust/pull/125779.

One current issue we have with "run" button and the newly added copy code button is that if you're on mobile devices, you can't use them. I took a look at how `mdbook` is handling it and when you click on a code example, they show the buttons. I think it's a really good idea as if you want to copy the code on your mobile device, you will click on it, showing the buttons.

Feature can be tested [here](https://rustdoc.crud.net/imperio/click-code-example/foo/struct.Bar.html).

r? `@notriddle`
2024-07-30 04:31:55 +02:00
Guillaume Gomez
99906dc89c Add rustdoc GUI test to check click on code examples 2024-07-29 21:14:36 +02:00
Michael Howell
3bf8bcfbe0 rustdoc: properly handle path wrapping 2024-07-29 10:31:02 -07:00
Michael Howell
0d0e18e7f6 rustdoc: use <wbr>-tolerant function to check text contents 2024-07-29 08:46:11 -07:00
Guillaume Gomez
a8cc24a1ab
Rollup merge of #125779 - GuillaumeGomez:copy-code, r=rustdoc-team
[rustdoc] Add copy code feature

This PR adds a "copy code" to code blocks. Since this is a JS only feature, the HTML is generated with JS when the user hovers the code block to prevent generating DOM unless needed.

Two things to note:
 1. I voluntarily kept the current behaviour of the run button (only when hovering a code block with a mouse) so it doesn't do anything on mobile. I plan to send a follow-up where the buttons would "expandable" or something. Still need to think which approach would be the best.
 2. I used a picture and not text like the run button to remain consistent with the "copy path" button. I'd also prefer for the run button to use a picture (like what is used in mdbook) but again, that's something to be discussed later on.

The rendering looks like this:

![Screenshot from 2024-06-03 21-29-48](https://github.com/rust-lang/rust/assets/3050060/a0b18f9c-b3dd-4a65-89a7-5a7a303b5c2b)
![Screenshot from 2024-06-03 21-30-20](https://github.com/rust-lang/rust/assets/3050060/b3b084ff-2716-4160-820b-d4774681a961)

It can be tested [here](https://guillaume-gomez.fr/rustdoc/bar/struct.Bar.html) (without the run button) and [here](https://guillaume-gomez.fr/rustdoc/foo/struct.Bar.html) (with the run button).

Fixes #86851.

r? ``@notriddle``
2024-07-28 20:07:44 +02:00
Guillaume Gomez
015f5d6f76 Add rustdoc GUI test to check title with and without search 2024-07-27 12:12:16 +02:00
Guillaume Gomez
7de26684e8 Add regression test for items list size (#128023) 2024-07-22 11:33:03 +02:00
Jubilee
5bd7525856
Rollup merge of #128014 - GuillaumeGomez:stab-in-doc-blocks, r=notriddle
Fix stab display in doc blocks

Went across this bug randomly:

![Screenshot from 2024-07-20 22-09-49](https://github.com/user-attachments/assets/89fdf427-b00e-4fcb-9d57-078bcb1bacd9)

With the fixed CSS:

![Screenshot from 2024-07-20 22-10-14](https://github.com/user-attachments/assets/eda9a1a6-6a12-408f-bd3a-25bb3397d163)

r? ```@notriddle```
2024-07-21 17:44:28 -07:00
Guillaume Gomez
84db684f49 Update source-code-page-code-scroll.goml GUI test 2024-07-21 12:47:34 +02:00
Guillaume Gomez
e4d701b1d3 Add regression test for stab display in doc blocks 2024-07-21 11:52:24 +02:00
Guillaume Gomez
eec3c3db88 Add GUI test for trait bounds display 2024-07-19 21:31:30 +02:00
Guillaume Gomez
590c01a5c5 Reduce width to ensure that the name is wider and thus still triggering the scroll 2024-07-19 21:31:30 +02:00
Matthias Krüger
1c665738de
Rollup merge of #127932 - notriddle:notriddle/current, r=GuillaumeGomez
rustdoc: fix `current` class on sidebar modnav

| Before | After |
| -- | -- |
| ![image](https://github.com/user-attachments/assets/35866be8-5a58-41eb-9169-b2bb403fe7cd) | ![image](https://github.com/user-attachments/assets/89b087ea-82bf-49f5-9c87-20162880eb32)
2024-07-19 10:48:06 +02:00
Michael Howell
2e1e627430 rustdoc: fix current class on sidebar modnav 2024-07-18 12:06:21 -07:00
Guillaume Gomez
c820a2392c Add test for size of items in the items list 2024-07-18 20:48:20 +02:00
Guillaume Gomez
26d72512e0 Unify UI between code block buttons and top buttons 2024-07-18 14:16:29 +02:00
Guillaume Gomez
578810b4d2 Make "copy code" button the same size as the "copy path" button 2024-07-18 14:16:29 +02:00
Guillaume Gomez
ddaa90fc56 Add rustdoc GUI test for new copy code feature 2024-07-18 14:16:29 +02:00
Michael Howell
55149061ea rustdoc: add test cases for mile wide bar 2024-07-16 13:29:35 -07:00
Michael Howell
3924493a10 rustdoc: make sidebar highlight cover whole click target 2024-07-15 17:44:05 -07:00
Guillaume Gomez
9855a3844b Add tests for new toggle on deref blocks 2024-07-15 20:07:24 +02:00
Michael Howell
5fc30b857c rustdoc: click target for sidebar items flush left 2024-07-01 18:03:58 -07:00
Guillaume Gomez
c8bbeef12f Don't call switch-theme function 2024-06-29 11:56:06 +02:00
Guillaume Gomez
b1d1e66389 Add back help-page.goml rustdoc GUI test 2024-06-29 11:56:06 +02:00
Guillaume Gomez
315be7d483 Update browser-ui-test version to 0.18.0 2024-06-27 00:04:23 +02:00
Guillaume Gomez
9e466d3361 Remove failing GUI test to stop blocking CI until it is fixed 2024-06-14 00:49:05 +02:00
Matthias Krüger
7af9ad1465
Rollup merge of #124738 - notriddle:notriddle/search-form-js, r=GuillaumeGomez
rustdoc: dedup search form HTML

This change constructs the search form HTML using JavaScript, instead of plain HTML. It uses a custom element because

- the [parser]'s insert algorithm runs the connected callback synchronously, so we won't get layout jank
- it requires very little HTML, so it's a real win in size

[parser]: https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token

This shrinks the standard library by about 60MiB, by my test.

There should be no visible changes. Just use less disk space.
2024-05-07 18:12:54 +02:00
Guillaume Gomez
e460901b13 Add GUI regression test for setting's cog color 2024-05-05 20:07:12 +02:00
Guillaume Gomez
0cbebd07ee Fix bad color for setting cog in ayu theme 2024-05-05 20:07:12 +02:00
Michael Howell
eeb59f16a5 rustdoc: dedup search form HTML
This change constructs the search form HTML using JavaScript, instead of plain HTML. It uses a custom element because

- the [parser]'s insert algorithm runs the connected callback synchronously, so we won't get layout jank
- it requires very little HTML, so it's a real win in size

[parser]: https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token

This shrinks the standard library by about 60MiB, by my test.
2024-05-05 08:15:08 -07:00
Matthias Krüger
e9b0c91cdd
Rollup merge of #124197 - GuillaumeGomez:move-duplicated-code, r=notriddle
Move duplicated code in functions in `tests/rustdoc-gui/notable-trait.goml`

It also allowed me to add some new common test like:

```
        assert-position: (
            "//*[`@class='tooltip` popover']",
            {"x": |popover_x|}
        )
```

r? `@notriddle`
2024-04-23 06:24:56 +02:00
Guillaume Gomez
dd01f75a89 Move duplicated code in functions in tests/rustdoc-gui/notable-trait.goml 2024-04-20 14:53:14 +02:00
Guillaume Gomez
1ebc9efa78 Add GUI test for copy path button 2024-04-17 16:56:14 +02:00
Michael Howell
3a007dbea9 rustdoc: update test cases 2024-04-09 20:22:13 -07:00
Guillaume Gomez
66bc97cc88 Make theme switching closer to reality 2024-04-08 12:14:41 +02:00
Guillaume Gomez
53c5a69dfd Move check-container-color's code into check-search-color function 2024-04-06 15:52:00 +02:00
Guillaume Gomez
2b1c799636 Move duplicated code into check-search-color function 2024-04-06 15:47:12 +02:00
Guillaume Gomez
f14e4db1f9 Move more common code into a function in tests/rustdoc-gui/search-result-color.goml 2024-04-06 15:24:09 +02:00
Guillaume Gomez
4967895e55 Move search-result-color.goml common parts into a function 2024-04-06 14:53:30 +02:00