1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package static // import "miniflux.app/v2/internal/ui/static"
import (
"bytes"
"crypto/sha256"
"embed"
"fmt"
"github.com/tdewolff/minify/v2"
"github.com/tdewolff/minify/v2/css"
"github.com/tdewolff/minify/v2/js"
)
// Static assets.
var (
StylesheetBundleChecksums map[string]string
StylesheetBundles map[string][]byte
JavascriptBundleChecksums map[string]string
JavascriptBundles map[string][]byte
)
//go:embed bin/*
var binaryFiles embed.FS
//go:embed css/*.css
var stylesheetFiles embed.FS
//go:embed js/*.js
var javascriptFiles embed.FS
var binaryFileChecksums map[string]string
// CalculateBinaryFileChecksums generates hash of embed binary files.
func CalculateBinaryFileChecksums() error {
binaryFileChecksums = make(map[string]string)
dirEntries, err := binaryFiles.ReadDir("bin")
if err != nil {
return err
}
for _, dirEntry := range dirEntries {
data, err := LoadBinaryFile(dirEntry.Name())
if err != nil {
return err
}
binaryFileChecksums[dirEntry.Name()] = fmt.Sprintf("%x", sha256.Sum256(data))
}
return nil
}
// LoadBinaryFile loads an embed binary file.
func LoadBinaryFile(filename string) ([]byte, error) {
return binaryFiles.ReadFile(fmt.Sprintf(`bin/%s`, filename))
}
// GetBinaryFileChecksum returns a binary file checksum.
func GetBinaryFileChecksum(filename string) (string, error) {
if _, found := binaryFileChecksums[filename]; !found {
return "", fmt.Errorf(`static: unable to find checksum for %q`, filename)
}
return binaryFileChecksums[filename], nil
}
// GenerateStylesheetsBundles creates CSS bundles.
func GenerateStylesheetsBundles() error {
var bundles = map[string][]string{
"light_serif": {"css/light.css", "css/serif.css", "css/common.css"},
"light_sans_serif": {"css/light.css", "css/sans_serif.css", "css/common.css"},
"dark_serif": {"css/dark.css", "css/serif.css", "css/common.css"},
"dark_sans_serif": {"css/dark.css", "css/sans_serif.css", "css/common.css"},
"system_serif": {"css/system.css", "css/serif.css", "css/common.css"},
"system_sans_serif": {"css/system.css", "css/sans_serif.css", "css/common.css"},
}
StylesheetBundles = make(map[string][]byte)
StylesheetBundleChecksums = make(map[string]string)
minifier := minify.New()
minifier.AddFunc("text/css", css.Minify)
for bundle, srcFiles := range bundles {
var buffer bytes.Buffer
for _, srcFile := range srcFiles {
fileData, err := stylesheetFiles.ReadFile(srcFile)
if err != nil {
return err
}
buffer.Write(fileData)
}
minifiedData, err := minifier.Bytes("text/css", buffer.Bytes())
if err != nil {
return err
}
StylesheetBundles[bundle] = minifiedData
StylesheetBundleChecksums[bundle] = fmt.Sprintf("%x", sha256.Sum256(minifiedData))
}
return nil
}
// GenerateJavascriptBundles creates JS bundles.
func GenerateJavascriptBundles() error {
var bundles = map[string][]string{
"app": {
"js/dom_helper.js",
"js/touch_handler.js",
"js/keyboard_handler.js",
"js/request_builder.js",
"js/modal_handler.js",
"js/app.js",
"js/bootstrap.js",
},
"service-worker": {
"js/service_worker.js",
},
}
var prefixes = map[string]string{
"app": "(function(){'use strict';",
}
var suffixes = map[string]string{
"app": "})();",
}
JavascriptBundles = make(map[string][]byte)
JavascriptBundleChecksums = make(map[string]string)
minifier := minify.New()
minifier.AddFunc("text/javascript", js.Minify)
for bundle, srcFiles := range bundles {
var buffer bytes.Buffer
if prefix, found := prefixes[bundle]; found {
buffer.WriteString(prefix)
}
for _, srcFile := range srcFiles {
fileData, err := javascriptFiles.ReadFile(srcFile)
if err != nil {
return err
}
buffer.Write(fileData)
}
if suffix, found := suffixes[bundle]; found {
buffer.WriteString(suffix)
}
minifiedData, err := minifier.Bytes("text/javascript", buffer.Bytes())
if err != nil {
return err
}
JavascriptBundles[bundle] = minifiedData
JavascriptBundleChecksums[bundle] = fmt.Sprintf("%x", sha256.Sum256(minifiedData))
}
return nil
}
|