@@ -18,9 +18,6 @@ import (
1818)
1919
2020type materialIconRulesData struct {
21- IconDefinitions map [string ]* struct {
22- IconPath string `json:"iconPath"`
23- } `json:"iconDefinitions"`
2421 FileNames map [string ]string `json:"fileNames"`
2522 FolderNames map [string ]string `json:"folderNames"`
2623 FileExtensions map [string ]string `json:"fileExtensions"`
@@ -36,6 +33,7 @@ type MaterialIconProvider struct {
3633var materialIconProvider MaterialIconProvider
3734
3835func DefaultMaterialIconProvider () * MaterialIconProvider {
36+ materialIconProvider .once .Do (materialIconProvider .loadData )
3937 return & materialIconProvider
4038}
4139
@@ -64,7 +62,7 @@ func (m *MaterialIconProvider) loadData() {
6462 log .Debug ("Loaded material icon rules and SVG images" )
6563}
6664
67- func (m * MaterialIconProvider ) renderFileIconSVG (ctx reqctx.RequestContext , name , svg string ) template.HTML {
65+ func (m * MaterialIconProvider ) renderFileIconSVG (ctx reqctx.RequestContext , name , svg , extraClass string ) template.HTML {
6866 data := ctx .GetData ()
6967 renderedSVGs , _ := data ["_RenderedSVGs" ].(map [string ]bool )
7068 if renderedSVGs == nil {
@@ -77,7 +75,7 @@ func (m *MaterialIconProvider) renderFileIconSVG(ctx reqctx.RequestContext, name
7775 panic ("Invalid SVG icon" )
7876 }
7977 svgID := "svg-mfi-" + name
80- svgCommonAttrs := `class="svg fileicon " width="16" height="16" aria-hidden="true"`
78+ svgCommonAttrs := `class="svg git-entry-icon ` + extraClass + ` " width="16" height="16" aria-hidden="true"`
8179 posOuterBefore := strings .IndexByte (svg , '>' )
8280 if renderedSVGs [svgID ] && posOuterBefore != - 1 {
8381 return template .HTML (`<svg ` + svgCommonAttrs + `><use xlink:href="#` + svgID + `"></use></svg>` )
@@ -88,63 +86,82 @@ func (m *MaterialIconProvider) renderFileIconSVG(ctx reqctx.RequestContext, name
8886}
8987
9088func (m * MaterialIconProvider ) FileIcon (ctx reqctx.RequestContext , entry * git.TreeEntry ) template.HTML {
91- m .once .Do (m .loadData )
92-
9389 if m .rules == nil {
9490 return BasicThemeIcon (entry )
9591 }
9692
9793 if entry .IsLink () {
9894 if te , err := entry .FollowLink (); err == nil && te .IsDir () {
99- return svg .RenderHTML ("material-folder-symlink" )
95+ // keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work
96+ return svg .RenderHTML ("material-folder-symlink" , 16 , "octicon-file-directory-symlink" )
10097 }
10198 return svg .RenderHTML ("octicon-file-symlink-file" ) // TODO: find some better icons for them
10299 }
103100
104- name := m .findIconName (entry )
101+ name := m .findIconNameByGit (entry )
105102 if name == "folder" {
106103 // the material icon pack's "folder" icon doesn't look good, so use our built-in one
107- return svg .RenderHTML ("material-folder-generic" )
104+ // keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work
105+ return svg .RenderHTML ("material-folder-generic" , 16 , "octicon-file-directory-fill" )
108106 }
109107 if iconSVG , ok := m .svgs [name ]; ok && iconSVG != "" {
110- return m .renderFileIconSVG (ctx , name , iconSVG )
108+ // keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work
109+ extraClass := "octicon-file"
110+ switch {
111+ case entry .IsDir ():
112+ extraClass = "octicon-file-directory-fill"
113+ case entry .IsSubModule ():
114+ extraClass = "octicon-file-submodule"
115+ }
116+ return m .renderFileIconSVG (ctx , name , iconSVG , extraClass )
111117 }
112118 return svg .RenderHTML ("octicon-file" )
113119}
114120
115- func (m * MaterialIconProvider ) findIconName ( entry * git. TreeEntry ) string {
116- if entry . IsSubModule () {
117- return "folder-git"
121+ func (m * MaterialIconProvider ) findIconNameWithLangID ( s string ) string {
122+ if _ , ok := m . svgs [ s ]; ok {
123+ return s
118124 }
119-
120- iconsData := m .rules
121- fileName := path .Base (entry .Name ())
122-
123- if entry .IsDir () {
124- if s , ok := iconsData .FolderNames [fileName ]; ok {
125+ if s , ok := m .rules .LanguageIDs [s ]; ok {
126+ if _ , ok = m .svgs [s ]; ok {
125127 return s
126128 }
127- if s , ok := iconsData .FolderNames [strings .ToLower (fileName )]; ok {
129+ }
130+ return ""
131+ }
132+
133+ func (m * MaterialIconProvider ) FindIconName (name string , isDir bool ) string {
134+ fileNameLower := strings .ToLower (path .Base (name ))
135+ if isDir {
136+ if s , ok := m .rules .FolderNames [fileNameLower ]; ok {
128137 return s
129138 }
130139 return "folder"
131140 }
132141
133- if s , ok := iconsData .FileNames [fileName ]; ok {
134- return s
135- }
136- if s , ok := iconsData .FileNames [strings .ToLower (fileName )]; ok {
137- return s
142+ if s , ok := m .rules .FileNames [fileNameLower ]; ok {
143+ if s = m .findIconNameWithLangID (s ); s != "" {
144+ return s
145+ }
138146 }
139147
140- for i := len (fileName ) - 1 ; i >= 0 ; i -- {
141- if fileName [i ] == '.' {
142- ext := fileName [i + 1 :]
143- if s , ok := iconsData .FileExtensions [ext ]; ok {
144- return s
148+ for i := len (fileNameLower ) - 1 ; i >= 0 ; i -- {
149+ if fileNameLower [i ] == '.' {
150+ ext := fileNameLower [i + 1 :]
151+ if s , ok := m .rules .FileExtensions [ext ]; ok {
152+ if s = m .findIconNameWithLangID (s ); s != "" {
153+ return s
154+ }
145155 }
146156 }
147157 }
148158
149159 return "file"
150160}
161+
162+ func (m * MaterialIconProvider ) findIconNameByGit (entry * git.TreeEntry ) string {
163+ if entry .IsSubModule () {
164+ return "folder-git"
165+ }
166+ return m .FindIconName (entry .Name (), entry .IsDir ())
167+ }
0 commit comments