-
Notifications
You must be signed in to change notification settings - Fork 1
/
js.go
101 lines (91 loc) · 2.62 KB
/
js.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
92
93
94
95
96
97
98
99
100
101
package jaws
import (
"bytes"
"compress/gzip"
_ "embed"
"hash/fnv"
"html/template"
"strconv"
"strings"
)
//go:embed jaws.js
var javascriptText []byte
var javascriptGZip []byte
var javascriptPath string
// JavascriptText returns the source code for the client-side JaWS Javascript library.
func JavascriptText() []byte {
return javascriptText
}
// JavascriptGZip returns the embedded Javascript library GZipped.
func JavascriptGZip() []byte {
if javascriptGZip == nil {
b := bytes.Buffer{}
gw := gzip.NewWriter(&b)
_, err := gw.Write(JavascriptText())
maybePanic(err)
maybePanic(gw.Close())
javascriptGZip = b.Bytes()
}
return javascriptGZip
}
// JavascriptPath returns the path for the embedded JaWS Javascript library.
func JavascriptPath() string {
if javascriptPath == "" {
h := fnv.New64a()
_, err := h.Write(JavascriptText())
maybePanic(err)
javascriptPath = "/jaws/jaws." + strconv.FormatUint(h.Sum64(), 36) + ".js"
}
return javascriptPath
}
func appendLinkStyleSheet(s []byte, css string) []byte {
s = append(s, `<link rel="stylesheet" href="`...)
s = append(s, css...)
s = append(s, `">`...)
return s
}
// HeadHTML returns the HTML code to load the required CSS and Javascript
// libraries along with any `*.js“ and `*.css` URL's given in `extra`.
// Place the returned HTML code in the HEAD section of the document.
func HeadHTML(jawsKey uint64, extra ...string) template.HTML {
const forEachPart = `.forEach(function(c){var e=document.createElement("script");e.src=c;e.async=!1;document.head.appendChild(e);});`
keyStr := JawsKeyString(jawsKey)
bsJS := bootstrapConfig.bootstrapJS
bsCSS := bootstrapConfig.bootstrapCSS
jawsJS := JavascriptPath()
need := 21 + len(keyStr) + 4 + len(bsJS) + 3 + len(jawsJS) + 2 + len(forEachPart) + 9 + len(bsCSS) + 31 + 18
for _, e := range extra {
need += 3 + len(e)
if strings.HasSuffix(e, ".css") {
need += 31 - 3
}
}
s := make([]byte, 0, need)
s = append(s, `<script>var jawsKey="`...)
s = append(s, keyStr...)
s = append(s, `";["`...)
s = append(s, bsJS...)
s = append(s, `","`...)
s = append(s, jawsJS...)
for _, e := range extra {
if strings.HasSuffix(e, ".js") {
s = append(s, `","`...)
s = append(s, e...)
}
}
s = append(s, `"]`+forEachPart+`</script>`...)
s = appendLinkStyleSheet(s, bsCSS)
for _, e := range extra {
if strings.HasSuffix(e, ".css") {
s = appendLinkStyleSheet(s, e)
}
}
s = append(s, `<script>0</script>`...) // forces FireFox to evaluate now
return template.HTML(s) // #nosec G203
}
func JawsKeyString(jawsKey uint64) string {
if jawsKey == 0 {
return ""
}
return strconv.FormatUint(jawsKey, 16)
}