5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-04 02:51:56 +08:00

Merge pull request #715

* Fixed multi-line tags being minified incorrectly. Fixed self closing …

* Improved html whitespace minification fix.
This commit is contained in:
Alexander Hudek 2021-05-15 23:22:44 -04:00 committed by GitHub
parent 6ab1a4adb0
commit 101d344303
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 201 additions and 17 deletions

View File

@ -52,21 +52,13 @@ func (a *Asset) AsString() string {
return a.Data
}
// AsCHexData processes the asset data so it may be used by C
func (a *Asset) AsCHexData() string {
// This will be our final string to hexify
dataString := a.Data
func (a *Asset) minifiedData() (string, error) {
switch a.Type {
case AssetTypes.HTML:
// Escape HTML
var re = regexp.MustCompile(`\s{2,}`)
result := re.ReplaceAllString(a.Data, ``)
result = strings.ReplaceAll(result, "\n", "")
result = strings.ReplaceAll(result, "\r\n", "")
result = strings.ReplaceAll(result, "\n", "")
var re = regexp.MustCompile(`[\s]+`)
result := re.ReplaceAllString(a.Data, ` `)
// Inject wailsloader code
result = strings.Replace(result, `</body>`, `<script id='wailsloader'>window.wailsloader = { html: true, runtime: false, userjs: false, usercss: false };var self=document.querySelector('#wailsloader');self.parentNode.removeChild(self);</script></body>`, 1)
@ -75,7 +67,7 @@ func (a *Asset) AsCHexData() string {
urlString := strings.ReplaceAll(url.String(), "/", "%2f")
// Save Data uRI string
dataString = "data:text/html;charset=utf-8," + urlString
return "data:text/html;charset=utf-8," + urlString, nil
case AssetTypes.CSS:
@ -91,19 +83,28 @@ func (a *Asset) AsCHexData() string {
result = strings.ReplaceAll(result, `'`, `\'`)
result = strings.ReplaceAll(result, ` {`, `{`)
result = strings.ReplaceAll(result, `: `, `:`)
dataString = fmt.Sprintf("window.wails._.InjectCSS(\"%s\");", result)
return fmt.Sprintf("window.wails._.InjectCSS(\"%s\");", result), nil
case AssetTypes.JS:
m := minify.New()
m.AddFunc("application/javascript", js.Minify)
var err error
dataString, err = m.String("application/javascript", a.Data+";")
result, err := m.String("application/javascript", a.Data+";")
if err != nil {
log.Fatal(err)
return "", err
}
a.Data = dataString
return result, nil
default:
return "", fmt.Errorf("minification for asset type %s not implemented", a.Type)
}
}
// AsCHexData processes the asset data so it may be used by C
func (a *Asset) AsCHexData() string {
dataString, err := a.minifiedData()
if err != nil {
log.Fatal(err)
}
// Get byte data of the string
bytes := *(*[]byte)(unsafe.Pointer(&dataString))

View File

@ -0,0 +1,53 @@
package html
import "testing"
func TestAsset_minifiedData(t *testing.T) {
type fields struct {
Type string
Path string
Data string
}
tests := []struct {
name string
fields fields
want string
wantErr bool
}{
{
name: "multi-line tag",
fields: fields{
Type: AssetTypes.HTML,
Path: "foo.html",
Data: "<link\n rel=\"stylesheet\"\n href=\"src/foo.css\"\n>\n",
},
want: "data:text/html;charset=utf-8,%3Clink%20rel=%22stylesheet%22%20href=%22src%2ffoo.css%22%20%3E%20",
},
{
name: "multi-line tag no spaces",
fields: fields{
Type: AssetTypes.HTML,
Path: "foo.html",
Data: "<link\nrel=\"stylesheet\"\nhref=\"src/foo.css\"\n>\n",
},
want: "data:text/html;charset=utf-8,%3Clink%20rel=%22stylesheet%22%20href=%22src%2ffoo.css%22%20%3E%20",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &Asset{
Type: tt.fields.Type,
Path: tt.fields.Path,
Data: tt.fields.Data,
}
got, err := a.minifiedData()
if (err != nil) != tt.wantErr {
t.Errorf("Asset.minifiedData() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("Asset.minifiedData() = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -84,7 +84,7 @@ func (a *AssetBundle) processHTML(htmldata string) error {
}
//process the token according to the token type...
if tokenType == html.StartTagToken {
if tokenType == html.StartTagToken || tokenType == html.SelfClosingTagToken {
//get the token
token := tokenizer.Token()

View File

@ -0,0 +1,73 @@
package html
import (
"testing"
)
func TestNewAssetBundle(t *testing.T) {
tests := []struct {
name string
pathToHTML string
wantAssets []string
wantErr bool
}{
{
name: "basic html",
pathToHTML: "testdata/basic.html",
wantAssets: []string{
AssetTypes.HTML,
AssetTypes.FAVICON,
AssetTypes.JS,
AssetTypes.CSS,
},
wantErr: false,
},
{
name: "self closing tags",
pathToHTML: "testdata/self_closing.html",
wantAssets: []string{
AssetTypes.HTML,
AssetTypes.FAVICON,
AssetTypes.JS,
AssetTypes.CSS,
},
wantErr: false,
},
{
name: "multi-line tags",
pathToHTML: "testdata/self_closing.html",
wantAssets: []string{
AssetTypes.HTML,
AssetTypes.FAVICON,
AssetTypes.JS,
AssetTypes.CSS,
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewAssetBundle(tt.pathToHTML)
if (err != nil) != tt.wantErr {
t.Errorf("NewAssetBundle() error = %v, wantErr %v", err, tt.wantErr)
return
}
if len(got.assets) != len(tt.wantAssets) {
t.Errorf("NewAssetBundle() len(assets) = %d, want %d",
len(got.assets), len(tt.wantAssets))
}
for i := range tt.wantAssets {
if i >= len(got.assets) {
t.Errorf("NewAssetBundle() missing assets[%d].Type = %s",
i, tt.wantAssets[i])
} else {
if got.assets[i].Type != tt.wantAssets[i] {
t.Errorf("NewAssetBundle() assets[%d].Type = %s, want %s",
i, got.assets[i].Type, tt.wantAssets[i])
}
}
}
})
}
}

14
v2/internal/html/testdata/basic.html vendored Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg"></link>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="text/javascript" src="src/bundle.js"></script>
<link rel="stylesheet" href="src/style.css"></link>
<title>Vite App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="text/javascript" src="src/bundle.js"></script>
<link
rel="stylesheet"
href="src/style.css"
/>
<title>Vite App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="text/javascript" src="src/bundle.js"></script>
<link rel="stylesheet" href="src/style.css" />
<title>Vite App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@ -0,0 +1 @@
window.alert("I am JS!");

View File

@ -0,0 +1,8 @@
<svg version="1.1"
baseProfile="full"
width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="blue" />
</svg>

After

Width:  |  Height:  |  Size: 172 B

View File

@ -0,0 +1,3 @@
.body {
background: blue;
}