Skip to content

top_menu: address review of #2904 - #4

Merged
lmiq merged 1 commit into
top_menu_from_pages2from
top_menu_review_fixes
Sep 29, 2026
Merged

lmiq merged 1 commit into
top_menu_from_pages2from
top_menu_review_fixes

Conversation

@lmiq

@lmiq lmiq commented Sep 29, 2026

Copy link
Copy Markdown
Owner

This PR addresses the review of the top_menu feature (JuliaDocs/Documenter.jl#2904). It targets top_menu_from_pages2 (#3), so the diff only contains the review fixes. Once #3 and this PR are merged into top_menu_from_pages, the changes will show up in JuliaDocs#2904.

Blockers

  1. Docs described the wrong API. The guide and the CHANGELOG now say that top_menu is an option of Documenter.HTML, and the guide example uses format = Documenter.HTML(top_menu = true).
    On the design question: I kept top_menu on HTML. A top bar with dropdowns is an HTML presentation feature, and for other writers the current structure is already right: LaTeX renders the first layer of pages as parts/chapters, which is the same hierarchy. The guide now says explicitly that other writers ignore the option. If we want this at the makedocs level later, it can be added without breaking HTML(top_menu = true).
  2. The new tests did not run.
    • The Logging problem is gone: the edge cases are now unit tests in test/topmenu.jl, and the duplicate-page warning is checked with @test_logs.
    • The empty-section test now uses an empty section next to a regular one, which is the top_menu-specific case. A build where every section is empty still hits the pre-existing BoundsError in render_sidebar, which also happens on master without top_menu. It is left for a separate fix.
    • The invalid-entry test now uses an existing page (pages = ["index.md"]). That gets past the "is not an existing page" check and reaches the new top_menu validation (item 5).
  3. prev/next crossed section boundaries. The footer now uses prev_next_navnodes, which keeps the previous/next links within the page's section when top_menu is on. NavNode.prev/.next are not modified, so other writers are unaffected. The example build tests that the first page of "User Guide" has no « link and the last page of "Getting Started" has no » link.
  4. hide() was ignored. TopMenuSection now stores visible. Sections hidden with hide("Title" => "page.md") are left out of the top bar, and hidden entries are left out of the dropdowns. In the reported example, hide("Sec B" => "other.md", ["hidden.md"]), the root stays visible (that is what hide(root, children) means), so "Sec B" is still in the top bar. But hidden.md is no longer listed in its dropdown; see also item 12.
  5. pages shape was not validated. Every top-level entry must now have a title. A bare "index.md" (or hide("index.md")) throws an error saying that the entry must be a "Section Title" => pages pair. "Title" => "page.md" is still accepted as a single-page section.
  6. Biome. Added the trailing comma in sidebar.js; make check-js passes.
  7. CHANGELOG. The entry now links [#2904] and adds the link definition. It was also sitting inside the already-released v1.17.0 section after the master merges; it is now under "Unreleased".

Should fix

  1. DOM.jl is reverted to master; the example and the full test suite pass without the change.
  2. Dead code: find_navnode_for_page is removed.
  3. Per-page linear scans: build_top_menu_sections now returns a page => section index Dict, stored in HTMLContext. The active-section lookup, the sidebar tree (get_section_navtree) and prev/next all use it through top_menu_section.
  4. The redirect index.html is removed, together with the suppression of the "src/index.md missing" warning and _find_first_index_page. A top_menu site now needs a root index.md, like any other site. The example build moves its landing page to src.topmenu/index.md. The redirect can be proposed separately.
  5. A section with a page and children lost its page. A section whose top node has a page now shows that node in the sidebar and dropdown, with its children nested under it; only title-only "Title" => [...] sections show their children directly. The example has a hide("Reference" => "reference/index.md", ["reference/extra.md"]) section to cover this.
  6. Unrelated churn: builder_pipeline.jl, documents.jl and docs/Project.toml are reverted to master.
  7. warnonly = true is removed from the html-topmenu example build, which builds without errors.

Minor

  • The guide now mentions that dropdowns are not shown on touch/small screens, where a section is reached through its title.
  • The caret now uses the Font Awesome chevron (\f078) through CSS, as the sidebar does, and is aria-hidden. The top <nav> has an aria-label, and the active section link has aria-current. Themes are recompiled.
  • The duplicated occursin("getting-started", ...) assertion is gone. The example tests now check the top menu <nav> and the sidebar <ul> separately, instead of searching the whole page.
  • The remaining end-to-end makedocs edge-case test uses mktempdir() do ... end, and the unused import Markdown is removed.

Testing

  • Pkg.test(): all top_menu tests pass (unit tests in test/topmenu.jl and the HTML: top_menu example testset). The only failures are three tests that compare against the JuliaDocs/Documenter.jl git remote (HTML: repo-* and two issue links in xrefs to Main), which fail in a checkout of a fork regardless of this change.
  • make check-js passes; Julia files are formatted with Runic.

AI disclosure: this change was prepared with the help of Claude Code (Claude Opus 5.5), and reviewed by me.

🤖 Generated with Claude Code

* Document `top_menu` as an option of `Documenter.HTML` (guide and
  CHANGELOG), move the CHANGELOG entry to Unreleased and link JuliaDocs#2904.
* Validate the shape of `pages`: every top-level entry must have a
  section title.
* Respect `hide`: hidden sections are not shown in the top menu, and
  hidden pages are not listed in the dropdowns.
* Keep the page of a section that is a page with sub-pages in the
  section's sidebar.
* Keep the previous/next page links within each section.
* Map pages to sections once, instead of scanning all sections for
  every rendered page; remove the unused `find_navnode_for_page`.
* Drop the redirect `index.html` feature, to be discussed separately.
* Use the icon font for the dropdown caret and add ARIA attributes.
* Revert unrelated changes (DOM.jl, builder_pipeline.jl, documents.jl,
  docs/Project.toml) and fix the Biome formatting of sidebar.js.
* Fix the tests: move the edge-case tests to unit tests in
  test/topmenu.jl, remove `warnonly` from the example build, and cover
  hidden sections, page + sub-pages sections and prev/next links.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lmiq
lmiq merged commit c23bac6 into top_menu_from_pages2 Sep 29, 2026
16 of 31 checks passed
@lmiq
lmiq deleted the top_menu_review_fixes branch September 29, 2026 16:56
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 36600101164

Warning

No base build found for commit 7d9b091 on top_menu_from_pages2.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 56.143%

Details

  • Patch coverage: 30 uncovered changes across 1 file (12 of 42 lines covered, 28.57%).

Uncovered Changes

File Changed Covered %
src/html/HTMLWriter.jl 40 10 25.0%
Total (3 files) 42 12 28.57%

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 5331
Covered Lines: 2993
Line Coverage: 56.14%
Coverage Strength: 291.72 hits per line

💛 - Coveralls

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