Skip to content
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

Replace navigation tree #315

Merged
merged 3 commits into from
Oct 5, 2023
Merged

Conversation

jonathanhefner
Copy link
Member

@jonathanhefner jonathanhefner commented Sep 28, 2023

The current navigation tree suffers from several problems:

  • From a UX perspective, when a navigation tree has many levels, interacting with the tree becomes tedious. Likewise, when a tree is very long, scanning becomes more difficult and it is easy to lose track of where you are in the hierarchy. For projects like Rails, the navigation tree has many levels and is very long.

  • The navigation tree uses JavaScript to navigate to pages instead of actual links. From a UX perspective, this can be frustrating when the user expects the entries to behave like links, such as when right-clicking or Ctrl+clicking. From an SEO perspective, it can be harmful because search engines cannot crawl the entries.

  • The CSS for the navigation tree is very brittle. The tree uses a repeating background image to achieve its striping effect, and requires entries to be a specific height to align with the background. This makes it difficult to change anything related to size, such as font size or even font family.

  • In terms of page rendering costs, the navigation tree can be very heavy for large projects. For Rails, the navigation tree adds several thousand nodes to the DOM. Furthermore, the tree is rendered entirely via JavaScript -- no static HTML -- which compounds the cost.

This commit replaces the navigation tree with a static sidebar per page. For the main page, the sidebar will display a list of top-level modules and a heading-based outline for the main page content. For other prose files (such as README files), the sidebar will similarly display a heading-based outline. For modules, the sidebar will display a list of their methods, as well as a heading-based outline if the module has a top-level comment that includes headings.

The filter.svg file is from Feather icons v4.29.0, and is licensed under the MIT license.

Before After
before1 after1a
after1b
before2 after2
before3 after3

The current navigation tree suffers from several problems:

* From a UX perspective, when a navigation tree has many levels,
  interacting with the tree becomes tedious.  Likewise, when a tree is
  very long, scanning becomes more difficult and it is easy to lose
  track of where you are in the hierarchy.  For projects like Rails, the
  navigation tree has many levels and is very long.

* The navigation tree uses JavaScript to navigate to pages instead of
  actual links.  From a UX perspective, this can be frustrating when the
  user expects the entries to behave like links, such as when
  right-clicking or Ctrl+clicking.  From an SEO perspective, it can be
  harmful because search engines cannot crawl the entries.

* The CSS for the navigation tree is very brittle.  The tree uses a
  repeating background image to achieve its striping effect, and
  requires entries to be a specific height to align with the background.
  This makes it difficult to change anything related to size, such as
  font size or even font family.

* In terms of page rendering costs, the navigation tree can be very
  heavy for large projects.  For Rails, the navigation tree adds several
  thousand nodes to the DOM.  Furthermore, the tree is rendered entirely
  via JavaScript -- no static HTML -- which compounds the cost.

This commit replaces the navigation tree with a static sidebar per page.
For the main page, the sidebar will display a list of top-level modules
and a heading-based outline for the main page content.  For other prose
files (such as `README` files), the sidebar will similarly display a
heading-based outline.  For modules, the sidebar will display a list of
their methods, as well as a heading-based outline if the module has a
top-level comment that includes headings.

The `filter.svg` file is from [Feather icons][feather] v4.29.0, and is
[licensed under the MIT license][license].

[feather]: https://feathericons.com/
[license]: https://github.com/feathericons/feather/blob/v4.29.0/LICENSE
There is currently a bug in RDoc v6.5.0 that causes the value of
`RDoc::ClassModule#in_files` to become polluted when referring to a
constant nested in a module where the module has been previously seen
but the constant has not.  For example, if RDoc sees a core extension
like:

  ```ruby
  class Float
    def as_json(*)
      # ...
    end
  end
  ```

and later sees a reference to `Float::INFINITY` in a file `foo.rb`, then
it will add `foo.rb` to `in_files` for `Float`.  That will cause
`foo.rb` to appear in `public/classes/Float.html` and `Float` to appear
in `public/files/foo.rb`.

This commit monkey patches RDoc to prevent such pollution.  The monkey
patch has been tested with the test suites of RDoc v6.5.0 and RDoc
`master` as of ruby/rdoc@9e75bf6, and
all tests pass.
The `--core-ext` option can be used to indicate files that define core
extensions.  It accepts a regular expression pattern.  If a module is
defined exclusively in files that match the pattern, the module will be
designated as a core extension and will be listed separately in the main
page nav.

The default value for `--core-ext` is `/core_ext/` which matches Rails'
core extension files in `activesupport/lib/active_support/core_ext/`.
@jonathanhefner jonathanhefner marked this pull request as ready for review October 5, 2023 18:26
@jonathanhefner jonathanhefner merged commit 97b8f31 into rails:main Oct 5, 2023
8 checks passed
@p8
Copy link
Member

p8 commented Oct 9, 2023

I'm wondering if we should move the page "table of contents" to the right side, similar to https://www.rubydoc.info/github/rails/rails. It think this makes it clearer that these belong to the current page.
image

Also, exploring for example "Active Record" is a bit more difficult right now. Maybe we should always show direct child modules in the sidebar?

@jonathanhefner
Copy link
Member Author

I'm wondering if we should move the page "table of contents" to the right side,

If we were to embed the table of contents in the main section, I would prefer it be left-aligned and below the <h1>, similar to how Wikipedia used to be. However, embedding the table of contents means that users would have to scroll back up to jump to a different section. In my opinion, having it in the sidebar (which scrolls independently) is more convenient, similar to how Wikipedia is now.

We could add a "Contents" label:

Before After
before after

Though I, personally, feel it is unnecessary.

Also, exploring for example "Active Record" is a bit more difficult right now. Maybe we should always show direct child modules in the sidebar?

By "exploring", do you mean reading through Active Record without a specific goal? I think that is a good use case to keep in mind, but I am not sure we want to design around it.

Adding the direct child modules to sidebar means either we duplicate the Namespace section, or we move it to the sidebar. I would prefer to not duplicate content, and having Namespace section in the sidebar has its own design challenges. For example, module names can be long (even without their full path) and may need to be truncated or wrapped, which makes them harder to browse / explore.

An alternative would be to bump the Namespace section higher up, though that would mean bumping other sections down — a trade-off. Another possibility would be to add a link in the sidebar to the Namespace section.

@p8
Copy link
Member

p8 commented Oct 9, 2023

If we were to embed the table of contents in the main section, I would prefer it be left-aligned and below the <h1>, similar to how Wikipedia used to be. However, embedding the table of contents means that users would have to scroll back up to jump to a different section. In my opinion, having it in the sidebar (which scrolls independently) is more convenient, similar to how Wikipedia is now.

The Tailwind documentation has it on the right side, scrolling independently. I'm not sure I like their implementation though.
https://tailwindcss.com/docs/editor-setup

We could add a "Contents" label ....
Though I, personally, feel it is unnecessary.

Hmm, I think that is more clear. The first time I visited this new implementation, I expected these TOC links to be the same on all pages. "What’s Rails?" seems like a common documentation title for a page that describes the project.
So to me it was confusing that this part of the sidebar changed when navigating to another page.
Maybe that's just because I'm used to the old navigation, which doesn't change.

It would be clearer to me that the TOC is related to the page if the list item that is currently in view would be highlighted:

image

By "exploring", do you mean reading through Active Record without a specific goal? I think that is a good use case to keep in mind, but I am not sure we want to design around it.

Sometimes I want to find documentation, but I can't recall the naming.
In the old implementation I would explore the sidebar tree.

I think this also helps with finding unknown methods.

Adding the direct child modules to sidebar means either we duplicate the Namespace section, or we move it to the sidebar. I would prefer to not duplicate content, and having Namespace section in the sidebar has its own design challenges. For example, module names can be long (even without their full path) and may need to be truncated or wrapped, which makes them harder to browse / explore.

An alternative would be to bump the Namespace section higher up, though that would mean bumping other sections down — a trade-off. Another possibility would be to add a link in the sidebar to the Namespace section.

I agree there isn't a simple solution, although the namespaces did seem to fit in the old implementation.

@jonathanhefner
Copy link
Member Author

although the namespaces did seem to fit in the old implementation.

The old implementation used a 13px proportional font. That is roughly equivalent to a 10.5px monospace font:

old-font

Both are illegibly small, in my opinion.

But I've submitted #328 to improve explorability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants