forked from vanng822/go-premailer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspecificity.go
68 lines (59 loc) · 1.48 KB
/
specificity.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
package premailer
import (
"regexp"
"strings"
)
// https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
// https://developer.mozilla.org/en-US/docs/Web/CSS/Reference#Selectors
type specificity struct {
important int
idCount int
classCount int
typeCount int
attrCount int
ruleSetIndex int
ruleIndex int
}
func (s *specificity) importantOrders() []int {
return []int{s.important, s.idCount,
s.classCount, s.attrCount,
s.typeCount, s.ruleSetIndex,
s.ruleIndex}
}
var typeSelectorRegex = regexp.MustCompile("(^|\\s)\\w")
func makeSpecificity(important, ruleSetIndex, ruleIndex int, selector string) *specificity {
spec := specificity{}
// determine values for priority
if important > 0 {
spec.important = 1
} else {
spec.important = 0
}
spec.idCount = strings.Count(selector, "#")
spec.classCount = strings.Count(selector, ".")
spec.attrCount = strings.Count(selector, "[")
spec.typeCount = len(typeSelectorRegex.FindAllString(selector, -1))
spec.ruleSetIndex = ruleSetIndex
spec.ruleIndex = ruleIndex
return &spec
}
type bySpecificity []*styleRule
func (bs bySpecificity) Len() int {
return len(bs)
}
func (bs bySpecificity) Swap(i, j int) {
bs[i], bs[j] = bs[j], bs[i]
}
func (bs bySpecificity) Less(i, j int) bool {
iorders := bs[i].specificity.importantOrders()
jorders := bs[j].specificity.importantOrders()
for n, v := range iorders {
if v < jorders[n] {
return true
}
if v > jorders[n] {
return false
}
}
return false
}