@@ -758,7 +758,7 @@ def generate_ancestor_list(ancestors, klass)
758758
759759 def generate_class_link ( klass , rel_prefix )
760760 if klass . display?
761- %(<code><a href=" #{ rel_prefix } / #{ klass . path } "> #{ klass . name } </a> </code>)
761+ %(<code>#{ generate_sidebar_link ( klass . name , klass . path , rel_prefix ) } </code>)
762762 else
763763 %(<code>#{ klass . name } </code>)
764764 end
@@ -768,25 +768,21 @@ def generate_class_index_content(classes, rel_prefix)
768768 grouped_classes = group_classes_by_namespace_for_sidebar ( classes )
769769 return '' unless top = grouped_classes [ nil ]
770770
771- solo = top . one? { |klass | klass . display? }
772- traverse_classes ( top , grouped_classes , rel_prefix , solo )
771+ open = top . one? { |klass | klass . display? }
772+ traverse_classes ( top , grouped_classes , rel_prefix , open )
773773 end
774774
775- def traverse_classes ( klasses , grouped_classes , rel_prefix , solo = false )
776- content = +'<ul class="link-list">'
777-
778- klasses . each do |index_klass |
779- if children = grouped_classes [ index_klass . full_name ]
780- content << %(<li><details#{ solo ? ' open' : '' } ><summary>#{ generate_class_link ( index_klass , rel_prefix ) } </summary>)
781- content << traverse_classes ( children , grouped_classes , rel_prefix )
782- content << '</details></li>'
783- solo = false
784- elsif index_klass . display?
785- content << %(<li>#{ generate_class_link ( index_klass , rel_prefix ) } </li>)
775+ def traverse_classes ( klasses , grouped_classes , rel_prefix , open )
776+ traverse_tree ( klasses ) do |index_klass |
777+ {
778+ label : generate_class_link ( index_klass , rel_prefix ) ,
779+ children : grouped_classes [ index_klass . full_name ] ,
780+ display : index_klass . display? ,
781+ open : open
782+ } . tap do
783+ open = false
786784 end
787785 end
788-
789- "#{ content } </ul>"
790786 end
791787
792788 def group_classes_by_namespace_for_sidebar ( classes )
@@ -800,41 +796,43 @@ def group_classes_by_namespace_for_sidebar(classes)
800796 grouped_classes
801797 end
802798
803- def generate_page_link ( file , rel_prefix )
804- %(<a href="#{ rel_prefix } /#{ h file . path } ">#{ h file . page_name } </a>)
799+ def generate_sidebar_link ( name , path , rel_prefix )
800+ name = CGI . escapeHTML ( name )
801+ path = CGI . escapeHTML ( path )
802+ %(<a href="#{ rel_prefix } /#{ path } ">#{ name } </a>)
805803 end
806804
807805 def generate_pages_index_content ( page_files , rel_prefix , current )
808806 return '' if page_files . empty?
809807
810808 dir = current &.full_name &.[]( /\A [^\/ ]+(?=\/ )/ ) || current &.page_name
809+ grouped_files = page_files . group_by { |f | f . full_name [ /\A [^\/ ]+(?=\/ )/ ] || f . page_name }
811810
812- content = +'<ul class="link-list">'
813- page_files . group_by do |f |
814- f . full_name [ /\A [^\/ ]+(?=\/ )/ ] || f . page_name
815- end . each do |n , grouped_files |
816- f = grouped_files . shift
817- if grouped_files . empty?
818- content << %(<li>#{ generate_page_link ( f , rel_prefix ) } </li>)
819- next
820- end
821-
822- content << %(<li><details#{ dir == n ? ' open' : '' } ><summary>)
823- if n == f . page_name
824- content << generate_page_link ( f , rel_prefix )
811+ traverse_tree ( grouped_files ) do |name , files |
812+ f = files . shift
813+ # If the group has only one file, we can just link to it
814+ if files . empty?
815+ { label : generate_sidebar_link ( f . page_name , f . path , rel_prefix ) , display : true }
825816 else
826- content << h ( n )
827- grouped_files . unshift ( f )
828- end
829- content << '</summary><ul class="link-list">'
830-
831- grouped_files . each do |f |
832- content << %(<li>#{ generate_page_link ( f , rel_prefix ) } </li>)
817+ label =
818+ # If the group has multiple files and the current file matches the group name
819+ # the label should be a link to the current file
820+ if name == f . page_name
821+ generate_sidebar_link ( f . page_name , f . path , rel_prefix )
822+ # Otherwise, the label should be the group name
823+ else
824+ files . unshift ( f )
825+ h ( name )
826+ end
827+ {
828+ label : label ,
829+ children : files ,
830+ display : true ,
831+ open : dir == name ,
832+ child_renderer : -> ( f ) { { label : generate_sidebar_link ( f . page_name , f . path , rel_prefix ) , display : true } }
833+ }
833834 end
834-
835- content << '</ul></details>'
836835 end
837- content << '</ul>'
838836 end
839837
840838 private
@@ -855,4 +853,27 @@ def generate_nesting_namespaces_breadcrumb klass, rel_prefix
855853 { name : namespace , path : path , self : klass . full_name == class_module &.full_name }
856854 end
857855 end
856+
857+ def traverse_tree ( items , &block )
858+ content = +'<ul class="link-list">'
859+
860+ items . each do |*args |
861+ result = yield ( *args )
862+ next unless result [ :display ]
863+
864+ if result [ :children ]
865+ content << %(<li><details#{ result [ :open ] ? ' open' : '' } ><summary>#{ result [ :label ] } </summary>)
866+ if result [ :child_renderer ]
867+ content << traverse_tree ( result [ :children ] ) { |item | result [ :child_renderer ] . call ( item ) }
868+ else
869+ content << traverse_tree ( result [ :children ] , &block )
870+ end
871+ content << '</details></li>'
872+ else
873+ content << %(<li>#{ result [ :label ] } </li>)
874+ end
875+ end
876+
877+ "#{ content } </ul>"
878+ end
858879end
0 commit comments