-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clean up toggle logic in rustdoc #83332
Comments
Also the way toggles are handled is a global click event that bubbles down. There's a very complicated It feels to me that adding a toggle should just be a matter of wrapping the relevant block in a toggle div + toggle, and at runtime we simply need to hook up event listeners. |
Also there are a whole bunch of hardcoded pixel values in the css that guess the sizes of toggle buttons. We ... shouldn't be doing that. |
Overall the toggle code needs a major refactor, I think. I can make my changes without such a refactor but I think we need to redo the JS/CSS side of this entirely. |
I am definitely 👍 on moving JS code to Rust.
Yeah,
Hmm, what does that mean? |
This is used to keep the toggle block the same size. This seems to be related to attribute rendering but I can't be sure since I can't get rustdoc to render any attributes on enum variants or struct fields. Those pixel values are roughly the size of the little +. We should never be doing this. |
That CSS that you linked to uses |
It was just an example, there are lots of manual margins throughout to make abspos on the toggle wrappers work right, and I don't think it should be necessary? |
So what do you think we should start with to clean this up? |
I think we should first come up with a plan as to how it should work, get that reviewed by the team, and then work on it. A very rough plan is:
|
As extra information: we have four kind of toggles iirc:
I opened an issue to improve the toggles for the documentation blocks already (here: #56442). Currently, the documentation follows the item it documents. In my idea, it could be simplified by making it a child of the item instead (in the DOM). Then we could eventually try to handle the toggle through CSS only, which would allow us to remove a lot of JS. I didn't look for the other toggles yet. |
Yeah restructuring toggles to be inside a wrapping element would be very good. We should unify these types of toggles so that their mechanism is exactly the same (but their css might be slightly different) |
Well, it's been in my TODO list for a while. 😆 |
Sounds good, I think if we're going to refactor this we should have a concrete plan in the issue before moving ahead though. |
The "only" thing missing is how to do it with CSS only. Someone suggested it but I didn't investigate it yet. Once we have a solution for this, we can go to the next step. Here is what I have in mind: we keep the current DOM but move the "docblock" elements into the element they document, as simple as that. From what I tested, it seems to be working as is but to be confirmed once again, I tested a while ago after all and some DOM changes happened in the meantime, but I think it'll still work. The only changes required would then be in the CSS once again and to check that there is no difference in the rendering. What we can do is maybe split the work between each kind of toggle and then merge the CSS at the end? I don't think we can merge all of them though. For example, I think that the types' fields/variants' toggles will still remain on their own. Only the logic will be the same. I expect a huge reduction of JS after this change. It would bring a huge improvement in the rendering speed. |
Well, it was easy enough to find: https://stackoverflow.com/a/17731854 I can send a first PR for the "normal" doc blocks then so we can have a base to discuss on. EDIT: Well, got super motivated and actually started the implementation. More to come soon. |
Honestly given the state of the code I'd prefer if we did it from scratch.
What do you mean? Yes, the code generating them will be in different spots, and their CSS will be different, but any relevant JS should be the same I think. |
Can you write a concrete plan first? I'm worried we'll do something similarly hard to work with. Though if it makes all the JS go away I guess it's fine either way. |
Update on the plan: @GuillaumeGomez started work on the HTML-ification in #83355. I did some additional work setting up CSS to use I've got one PR open (#84320) converting one more set of toggles to One open question: I've noticed there are some toggle types (undocumented items; sub-variants) that don't have corresponding settings entries. Should we add settings for these or (my preference) group them under some other setting? |
Thanks for taking point on this, @jsha! Overall I don't think every toggle must have a config option, rather config options are useful when asked for. Otherwise having lots of niche configs can be pretty confusing, indeed a lot of folks used to be confused by our hyperspecific toggle settings before. So basically: don't add a config unless someone asks, and if someone asks figure out if it their needs can be met without a config (but if not, nbd, just add it) |
Has there been a check on how the EDIT: Ah, the current implementation is working in iOS Safari because it happens to inherit |
I checked safari on iPad OS 1.13 and the toggle is displayed correctly.
|
…earth,Nemo157,GuillaumeGomez Use details tag for trait implementors. Part of rust-lang#83332 and following on from rust-lang#83337 and rust-lang#83355. This removes one category of JS-generated toggles (implementors), and replaces them with a `<details>` tag. This simplifies the JS, and fixes some bugs where things that were supposed to be hidden by the toggle were not hidden. Compare https://hoffman-andrews.com/rust/details-implementors/std/io/trait.Read.html#impl-Read vs https://doc.rust-lang.org/nightly/std/io/trait.Read.html#implementors. This introduces a `left: -23px` to put the toggle in the correct place, matching the current style for `.collapse-toggle`. It's worth noting this introduces a slight behavior change: since the entire line is now a `<summary>`, any part of the line is clickable. So for instance, in `impl Read for File`, clicking `impl` or `for` will collapse / expand the docs. Clicking `Read` or `File` still links to the appropriate documentation as before.
…earth,Nemo157,GuillaumeGomez Use details tag for trait implementors. Part of rust-lang#83332 and following on from rust-lang#83337 and rust-lang#83355. This removes one category of JS-generated toggles (implementors), and replaces them with a `<details>` tag. This simplifies the JS, and fixes some bugs where things that were supposed to be hidden by the toggle were not hidden. Compare https://hoffman-andrews.com/rust/details-implementors/std/io/trait.Read.html#impl-Read vs https://doc.rust-lang.org/nightly/std/io/trait.Read.html#implementors. This introduces a `left: -23px` to put the toggle in the correct place, matching the current style for `.collapse-toggle`. It's worth noting this introduces a slight behavior change: since the entire line is now a `<summary>`, any part of the line is clickable. So for instance, in `impl Read for File`, clicking `impl` or `for` will collapse / expand the docs. Clicking `Read` or `File` still links to the appropriate documentation as before.
…laumeGomez rustdoc: Convert sub-variant toggle to HTML Instead of creating a JS toggle, this injects details/summary for sub-variants of enums. This also fixes the CSS so that the toggle button does not jump when expanding/collapsing. Takes inspiration from rust-lang#83337 and should be considered part of rust-lang#83332. Not quite sure if the `.sub-variant` selectors could be further simplified? AFAICS it is only used in that place, and that does not seem to allow any recursion.
…earth,Nemo157,GuillaumeGomez Use details tag for trait implementors. Part of rust-lang#83332 and following on from rust-lang#83337 and rust-lang#83355. This removes one category of JS-generated toggles (implementors), and replaces them with a `<details>` tag. This simplifies the JS, and fixes some bugs where things that were supposed to be hidden by the toggle were not hidden. Compare https://hoffman-andrews.com/rust/details-implementors/std/io/trait.Read.html#impl-Read vs https://doc.rust-lang.org/nightly/std/io/trait.Read.html#implementors. This introduces a `left: -23px` to put the toggle in the correct place, matching the current style for `.collapse-toggle`. It's worth noting this introduces a slight behavior change: since the entire line is now a `<summary>`, any part of the line is clickable. So for instance, in `impl Read for File`, clicking `impl` or `for` will collapse / expand the docs. Clicking `Read` or `File` still links to the appropriate documentation as before.
Currently working on methods and trait implementations. |
Migrate trait and impl blocks' toggles into Part of rust-lang#83332 After this, I think only the "global" doc comment will be used as JS toggle. Once this PR is merged, I check what remains and remove them. There is one change that this PR brings: ![Screenshot from 2021-04-30 15-39-04](https://user-images.githubusercontent.com/3050060/116713412-0f9ce200-a9d5-11eb-979c-2e7a73d16706.png) ![Screenshot from 2021-04-30 15-39-07](https://user-images.githubusercontent.com/3050060/116713415-10357880-a9d5-11eb-9868-1ba9e5ebf65e.png) As you can see, I had to move the "undocumented" items below, they're not mixed with the others anymore. Unfortunately, I don't see a way to keep the current appearance without JS. As a a reminder, currently it looks like this: ![Screenshot from 2021-04-30 15-39-12](https://user-images.githubusercontent.com/3050060/116713547-31966480-a9d5-11eb-90bb-686042eefeec.png) ![Screenshot from 2021-04-30 15-39-15](https://user-images.githubusercontent.com/3050060/116713549-322efb00-a9d5-11eb-94a9-cfea073120db.png) r? `@jsha`
I updated #83332 (comment). So now only two things remain:
|
Working on the two last points. |
The main refactoring (switching to
There are some hardcoded negative offsets in the CSS, like |
Reopening because I think these JS functions (collapseNonInherent and collapseDocs) still deal with toggling open / closed sections and need cleaning up: rust/src/librustdoc/html/static/main.js Lines 888 to 1018 in 455c5e0
|
Also we still need to remove the onEachLazy(main.getElementsByClassName("loading-content"), function(e) {
e.remove();
}); |
I'll start by removing the "loading-content" and then check what I forgot to remove. But normally, there is no more toggle to deal with. |
…, r=GuillaumeGomez Move global click handlers to per-element ones. In rustdoc's main.js, we had an onclick handler for the whole document that would dispatch to handlers for various elements. This change attaches the handlers to the elements that trigger them, instead. This simplifies the code and avoids reimplementing the browser's bubbling functionality. As part of this change, change from a class to an id for help button. Move the handlers and associated code for highlighting source lines into source-script.js (and factor out a shared regex). Demo at https://hoffman-andrews.com/rust/bubble-bubble-toil-and-trouble/std/string/struct.String.html Note: this conflicts with / depends on rust-lang#85074. Once that's merged I'll rebase this and resolve conflicts. Part of rust-lang#83332. Thanks to `@Manishearth` for the [suggestion to not reimplement bubbling](rust-lang#83332 (comment)). r? `@GuillaumeGomez`
Rustdoc cleanup Part of rust-lang#83332. The goal of this PR is to remove a few unused things: * The "loading content" things are now unneeded. * Some toggle CSS rules were still there. * Some parts of the JS had a different indent, fixed it. r? `@jsha`
This may be related: it looks like the CSS for |
Great! We have one last cosmetic cleanup in #85289, then I think this is done. |
🎉 |
Alright, now I think this is well and truly done. Congrats all! |
I was working on #82114 and discovered that the toggle logic is written scattered all throughout
main.js
. This seems suboptimal; I'd rather not be generating HTML in main.js. A lot of the toggle logic does things like check the classes of nearby items, etc, which seems super brittle.I propose we move the toggle logic to Rust code instead; writing a
wrapToggle()
method that wraps some HTML in a toggle.Thoughts? @rust-lang/rustdoc
Might be worth creating a meta issue for reducing the size of main.js in general. We seem to do a fair amount of additional codegen there, not just for toggles.
The text was updated successfully, but these errors were encountered: