github.com/ngocphuongnb/tetua@v0.0.7-alpha/app/asset/asset.go (about) 1 package asset 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "path" 9 "path/filepath" 10 "strings" 11 12 "github.com/ngocphuongnb/tetua/app/config" 13 "github.com/ngocphuongnb/tetua/app/utils" 14 ) 15 16 type StaticAsset struct { 17 Name string `json:"name"` 18 Path string `json:"path"` 19 Type string `json:"type"` 20 Content string `json:"content"` 21 DisableMinify bool `json:"disable_minify"` 22 DisableInline bool `json:"disable_inline"` 23 } 24 25 type ThemeConfig struct { 26 Asset struct { 27 Dir string `json:"dir"` 28 DisableMinify []string `json:"disable_minify"` 29 DisableInline []string `json:"disable_inline"` 30 } `json:"asset"` 31 } 32 33 var themeAssetsBundled = false 34 var bundledAssets = []*StaticAsset{} 35 var assets []*StaticAsset 36 37 func Load(themeDir string, force bool) { 38 loadThemeAssets(themeDir, force) 39 40 for _, bundledAsset := range bundledAssets { 41 hasBundledAsset := false 42 for _, asset := range assets { 43 if bundledAsset.Name == asset.Name { 44 asset.Content = bundledAsset.Content 45 hasBundledAsset = true 46 break 47 } 48 } 49 50 if !hasBundledAsset { 51 assets = append(assets, bundledAsset) 52 } 53 } 54 } 55 56 func loadThemeAssets(themeDir string, force bool) { 57 if themeAssetsBundled && !force && !config.DEVELOPMENT { 58 return 59 } 60 61 assets = []*StaticAsset{ 62 { 63 Type: "css", 64 Name: "editor/tippy-6.3.7.min.css", 65 Path: path.Join(config.ROOT_DIR, "packages/editor/dist/tippy-6.3.7.min.css"), 66 }, 67 { 68 Type: "css", 69 Name: "editor/tippy-light-6.3.7.min.css", 70 Path: path.Join(config.ROOT_DIR, "packages/editor/dist/tippy-light-6.3.7.min.css"), 71 }, 72 { 73 Type: "css", 74 Name: "editor/style.css", 75 Path: path.Join(config.ROOT_DIR, "packages/editor/dist/style.css"), 76 }, 77 { 78 Type: "js", 79 Name: "editor/highlight-11.5.0.min.js", 80 Path: path.Join(config.ROOT_DIR, "packages/editor/dist/highlight-11.5.0.min.js"), 81 DisableMinify: true, 82 DisableInline: true, 83 }, 84 { 85 Type: "js", 86 Name: "editor/editor.js", 87 Path: path.Join(config.ROOT_DIR, "packages/editor/dist/editor.js"), 88 DisableMinify: true, 89 DisableInline: true, 90 }, 91 } 92 93 themeConfigFile := path.Join(themeDir, "theme.json") 94 themeConfig := &ThemeConfig{} 95 file, err := ioutil.ReadFile(themeConfigFile) 96 97 if err != nil { 98 panic(err) 99 } 100 101 if err := json.Unmarshal([]byte(file), themeConfig); err != nil { 102 panic(err) 103 } 104 105 assetDir := path.Join(themeDir, themeConfig.Asset.Dir) 106 themeAssets, err := filepath.Glob(assetDir + "/*/**") 107 108 if err != nil { 109 panic(err) 110 } 111 112 for _, themeAsset := range themeAssets { 113 themeAssetName := strings.Trim(strings.Replace(themeAsset, assetDir, "", -1), "/") 114 themeAssetType := path.Ext(themeAssetName) 115 116 if themeAssetType == ".css" { 117 themeAssetType = "css" 118 } else if themeAssetType == ".js" { 119 themeAssetType = "js" 120 } else { 121 themeAssetType = "other" 122 } 123 124 AppendAsset(&StaticAsset{ 125 Name: themeAssetName, 126 Path: themeAsset, 127 Type: themeAssetType, 128 DisableInline: themeAssetType == "other" || utils.SliceContains(themeConfig.Asset.DisableInline, themeAssetName), 129 DisableMinify: themeAssetType == "other" || utils.SliceContains(themeConfig.Asset.DisableMinify, themeAssetName), 130 }) 131 } 132 } 133 134 func AppendAsset(asset *StaticAsset) { 135 for _, a := range assets { 136 if a.Name == asset.Name { 137 return 138 } 139 } 140 141 assets = append(assets, asset) 142 } 143 144 func All() []*StaticAsset { 145 return assets 146 } 147 148 func decodeBase64(input string) string { 149 s, err := base64.StdEncoding.DecodeString(input) 150 if err != nil { 151 return "" 152 } 153 return string(s) 154 } 155 156 func getStaticFile(assetName, assetType string) *StaticAsset { 157 for _, file := range assets { 158 if file.Name == assetName && file.Type == assetType { 159 return file 160 } 161 } 162 163 return &StaticAsset{} 164 } 165 166 func CssFile(assetName string) string { 167 assetFile := getStaticFile(assetName, "css") 168 169 if !config.DEVELOPMENT && !assetFile.DisableInline && assetFile.Content != "" { 170 return fmt.Sprintf(`<style type="text/css" data-file="%s">%s</style>`, assetName, assetFile.Content) 171 } 172 173 return fmt.Sprintf( 174 `<link rel="stylesheet" href="%s" />`, 175 utils.Url(path.Join("/assets", assetName)), 176 ) 177 } 178 179 func JsFile(assetName string) string { 180 assetFile := getStaticFile(assetName, "js") 181 182 if !config.DEVELOPMENT && !assetFile.DisableInline && assetFile.Content != "" { 183 return fmt.Sprintf(`<script charset="utf-8" data-file="%s">%s</script>`, assetName, assetFile.Content) 184 } 185 186 return fmt.Sprintf( 187 `<script charset="utf-8" src="%s"></script>`, 188 utils.Url(path.Join("/assets", assetName)), 189 ) 190 } 191 192 func OtherFile(assetName string) string { 193 return utils.Url(path.Join("/assets", assetName)) 194 }