@@ -828,7 +828,7 @@ def generate_ancestor_list(ancestors, klass)
828828
829829 def generate_class_link ( klass , rel_prefix )
830830 if klass . display?
831- %(<code><a href=" #{ rel_prefix } / #{ klass . path } "> #{ klass . name } </a> </code>)
831+ %(<code>#{ generate_sidebar_link ( klass . name , klass . path , rel_prefix ) } </code>)
832832 else
833833 %(<code>#{ klass . name } </code>)
834834 end
@@ -838,25 +838,21 @@ def generate_class_index_content(classes, rel_prefix)
838838 grouped_classes = group_classes_by_namespace_for_sidebar ( classes )
839839 return '' unless top = grouped_classes [ nil ]
840840
841- solo = top . one? { |klass | klass . display? }
842- traverse_classes ( top , grouped_classes , rel_prefix , solo )
841+ open = top . one? { |klass | klass . display? }
842+ traverse_classes ( top , grouped_classes , rel_prefix , open )
843843 end
844844
845- def traverse_classes ( klasses , grouped_classes , rel_prefix , solo = false )
846- content = +'<ul class="link-list">'
847-
848- klasses . each do |index_klass |
849- if children = grouped_classes [ index_klass . full_name ]
850- content << %(<li><details#{ solo ? ' open' : '' } ><summary>#{ generate_class_link ( index_klass , rel_prefix ) } </summary>)
851- content << traverse_classes ( children , grouped_classes , rel_prefix )
852- content << '</details></li>'
853- solo = false
854- elsif index_klass . display?
855- content << %(<li>#{ generate_class_link ( index_klass , rel_prefix ) } </li>)
845+ def traverse_classes ( klasses , grouped_classes , rel_prefix , open )
846+ traverse_tree ( klasses ) do |index_klass |
847+ {
848+ label : generate_class_link ( index_klass , rel_prefix ) ,
849+ children : grouped_classes [ index_klass . full_name ] ,
850+ display : index_klass . display? ,
851+ open : open
852+ } . tap do
853+ open = false
856854 end
857855 end
858-
859- "#{ content } </ul>"
860856 end
861857
862858 def group_classes_by_namespace_for_sidebar ( classes )
@@ -870,41 +866,43 @@ def group_classes_by_namespace_for_sidebar(classes)
870866 grouped_classes
871867 end
872868
873- def generate_page_link ( file , rel_prefix )
874- %(<a href="#{ rel_prefix } /#{ h file . path } ">#{ h file . page_name } </a>)
869+ def generate_sidebar_link ( name , path , rel_prefix )
870+ name = CGI . escapeHTML ( name )
871+ path = CGI . escapeHTML ( path )
872+ %(<a href="#{ rel_prefix } /#{ path } ">#{ name } </a>)
875873 end
876874
877875 def generate_pages_index_content ( page_files , rel_prefix , current )
878876 return '' if page_files . empty?
879877
880878 dir = current &.full_name &.[]( /\A [^\/ ]+(?=\/ )/ ) || current &.page_name
879+ grouped_files = page_files . group_by { |f | f . full_name [ /\A [^\/ ]+(?=\/ )/ ] || f . page_name }
881880
882- content = +'<ul class="link-list">'
883- page_files . group_by do |f |
884- f . full_name [ /\A [^\/ ]+(?=\/ )/ ] || f . page_name
885- end . each do |n , grouped_files |
886- f = grouped_files . shift
887- if grouped_files . empty?
888- content << %(<li>#{ generate_page_link ( f , rel_prefix ) } </li>)
889- next
890- end
891-
892- content << %(<li><details#{ dir == n ? ' open' : '' } ><summary>)
893- if n == f . page_name
894- content << generate_page_link ( f , rel_prefix )
881+ traverse_tree ( grouped_files ) do |name , files |
882+ f = files . shift
883+ # If the group has only one file, we can just link to it
884+ if files . empty?
885+ { label : generate_sidebar_link ( f . page_name , f . path , rel_prefix ) , display : true }
895886 else
896- content << h ( n )
897- grouped_files . unshift ( f )
898- end
899- content << '</summary><ul class="link-list">'
900-
901- grouped_files . each do |f |
902- content << %(<li>#{ generate_page_link ( f , rel_prefix ) } </li>)
887+ label =
888+ # If the group has multiple files and the current file matches the group name
889+ # the label should be a link to the current file
890+ if name == f . page_name
891+ generate_sidebar_link ( f . page_name , f . path , rel_prefix )
892+ # Otherwise, the label should be the group name
893+ else
894+ files . unshift ( f )
895+ h ( name )
896+ end
897+ {
898+ label : label ,
899+ children : files ,
900+ display : true ,
901+ open : dir == name ,
902+ child_renderer : -> ( f ) { { label : generate_sidebar_link ( f . page_name , f . path , rel_prefix ) , display : true } }
903+ }
903904 end
904-
905- content << '</ul></details>'
906905 end
907- content << '</ul>'
908906 end
909907
910908 private
@@ -925,4 +923,27 @@ def generate_nesting_namespaces_breadcrumb klass, rel_prefix
925923 { name : namespace , path : path , self : klass . full_name == class_module &.full_name }
926924 end
927925 end
926+
927+ def traverse_tree ( items , &block )
928+ content = +'<ul class="link-list">'
929+
930+ items . each do |*args |
931+ result = yield ( *args )
932+ next unless result [ :display ]
933+
934+ if result [ :children ]
935+ content << %(<li><details#{ result [ :open ] ? ' open' : '' } ><summary>#{ result [ :label ] } </summary>)
936+ if result [ :child_renderer ]
937+ content << traverse_tree ( result [ :children ] ) { |item | result [ :child_renderer ] . call ( item ) }
938+ else
939+ content << traverse_tree ( result [ :children ] , &block )
940+ end
941+ content << '</details></li>'
942+ else
943+ content << %(<li>#{ result [ :label ] } </li>)
944+ end
945+ end
946+
947+ "#{ content } </ul>"
948+ end
928949end
0 commit comments