From e75c46b7ca0d10c2bc15d0329acf6cc5c9de9c3f Mon Sep 17 00:00:00 2001 From: Amp Date: Tue, 29 Sep 2026 09:23:51 +0000 Subject: [PATCH 01/11] Share Aliki class navigation across generated pages Generate one navigation data file and lazily render namespace branches. Keep a static class index for crawlability and offline fallback, and refresh navigation data with live-preview changes. Amp-Thread-ID: https://ampcode.com/threads/T-01a0ea31-9f66-7342-a269-34772e5428db Co-authored-by: Stanislav Katkov --- lib/rdoc/generator/aliki.rb | 35 ++++++++ .../generator/template/aliki/_footer.rhtml | 1 + lib/rdoc/generator/template/aliki/_head.rhtml | 10 +++ .../template/aliki/_sidebar_classes.rhtml | 3 +- .../generator/template/aliki/js/navigation.js | 53 +++++++++++++ .../template/aliki/table_of_contents.rhtml | 30 +++++++ lib/rdoc/server.rb | 6 +- test/rdoc/generator/aliki/navigation_test.rb | 79 +++++++++++++++++++ test/rdoc/generator/aliki_test.rb | 55 +++++++++++++ test/rdoc/rdoc_server_test.rb | 21 +++++ 10 files changed, 290 insertions(+), 3 deletions(-) create mode 100644 lib/rdoc/generator/template/aliki/js/navigation.js create mode 100644 lib/rdoc/generator/template/aliki/table_of_contents.rhtml create mode 100644 test/rdoc/generator/aliki/navigation_test.rb diff --git a/lib/rdoc/generator/aliki.rb b/lib/rdoc/generator/aliki.rb index 5157283b3a..09e21510fa 100644 --- a/lib/rdoc/generator/aliki.rb +++ b/lib/rdoc/generator/aliki.rb @@ -34,6 +34,7 @@ def generate generate_file_files generate_table_of_contents write_search_index + write_navigation_index copy_static @@ -121,6 +122,40 @@ def write_search_index File.write search_index_path, "var search_data = #{JSON.generate(data)};" end + ## + # Builds the shared class tree in sidebar order. Hidden namespaces retain + # their visible descendants, but do not receive links of their own. + + def build_navigation_index + setup + grouped = @classes.group_by { |klass| klass.full_name.rpartition('::').first } + build_nodes = ->(classes) { + classes.filter_map do |klass| + children = build_nodes.call(grouped[klass.full_name] || []) + next unless klass.display? || !children.empty? + + { + name: klass.name, + full_name: klass.full_name, + path: klass.display? ? klass.path : nil, + children: children + } + end + } + build_nodes.call(grouped[''] || []) + end + + ## + # Like search data, navigation uses a classic script so file:// works + # without fetch or a web server. + + def write_navigation_index + return if @dry_run + + FileUtils.mkdir_p 'js' + File.write 'js/navigation_data.js', "var navigation_data = #{JSON.generate(build_navigation_index, max_nesting: false)};" + end + ## # Returns the type signature of +method_attr+ as HTML with linked type names. # Returns nil if no type signature is present. diff --git a/lib/rdoc/generator/template/aliki/_footer.rhtml b/lib/rdoc/generator/template/aliki/_footer.rhtml index ae2f831443..ef46dac4e6 100644 --- a/lib/rdoc/generator/template/aliki/_footer.rhtml +++ b/lib/rdoc/generator/template/aliki/_footer.rhtml @@ -15,6 +15,7 @@ <% end %>