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  }