-
Notifications
You must be signed in to change notification settings - Fork 0
/
minify.go
91 lines (70 loc) · 1.44 KB
/
minify.go
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
package stork
import (
"regexp"
"strings"
"golang.org/x/net/html"
)
func minify(n *html.Node) {
spacing := regexp.MustCompile(`[ \r\n\t]+`)
iterate(n, func(n *html.Node) {
switch n.Type {
case html.TextNode:
if n.Parent != nil && (n.Parent.Data == "code" || n.Parent.Data == "pre") {
break
}
// replace all whitespace characters to a single space
n.Data = spacing.ReplaceAllString(n.Data, " ")
}
})
// trim according to inline/block rules
trimLeft(n, true)
trimRight(n, true)
}
func trimLeft(n *html.Node, trim bool) bool {
switch n.Type {
case html.ElementNode:
if blockTags[n.Data] {
trim = true
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
trim = trimLeft(c, trim)
}
if blockTags[n.Data] || n.Data == "br" {
return true
}
case html.TextNode:
if trim {
n.Data = strings.TrimLeft(n.Data, " \r\n\t")
if strings.TrimSpace(n.Data) == "" {
remove(n)
return trim
}
}
return false
}
return trim
}
func trimRight(n *html.Node, trim bool) bool {
switch n.Type {
case html.ElementNode:
if blockTags[n.Data] {
trim = true
}
for c := n.LastChild; c != nil; c = c.PrevSibling {
trim = trimRight(c, trim)
}
if blockTags[n.Data] || n.Data == "br" {
return true
}
case html.TextNode:
if trim {
n.Data = strings.TrimRight(n.Data, " \r\n\t")
if strings.TrimSpace(n.Data) == "" {
remove(n)
return trim
}
}
return false
}
return trim
}