@@ -21,25 +21,54 @@ import (
21
21
"github.com/gohugoio/hugo/transform"
22
22
)
23
23
24
+ type tag struct {
25
+ markup []byte
26
+ appendScript bool
27
+ }
28
+
29
+ var tags = []tag {
30
+ tag {markup : []byte ("<head>" ), appendScript : true },
31
+ tag {markup : []byte ("<HEAD>" ), appendScript : true },
32
+ tag {markup : []byte ("</body>" )},
33
+ tag {markup : []byte ("</BODY>" )},
34
+ }
35
+
24
36
// New creates a function that can be used
25
37
// to inject a script tag for the livereload JavaScript in a HTML document.
26
38
func New (port int ) transform.Transformer {
27
39
return func (ft transform.FromTo ) error {
28
40
b := ft .From ().Bytes ()
29
- endBodyTag := "</body>"
30
- match := [] byte ( endBodyTag )
31
- replaceTemplate := `<script data-no-instant>document.write('<script src="/livereload.js?port=%d&mindelay=10&v=2"></' + ' script>')</script>%s`
32
- replace := [] byte ( fmt . Sprintf ( replaceTemplate , port , endBodyTag ))
33
-
34
- newcontent := bytes . Replace ( b , match , replace , 1 )
35
- if len ( newcontent ) == len ( b ) {
36
- endBodyTag = "</BODY>"
37
- replace := [] byte ( fmt . Sprintf ( replaceTemplate , port , endBodyTag ))
38
- match := [] byte ( endBodyTag )
39
- newcontent = bytes . Replace ( b , match , replace , 1 )
41
+ var idx = - 1
42
+ var match tag
43
+ // We used to insert the livereload script right before the closing body.
44
+ // This does not work when combined with tools such as Turbolinks.
45
+ // So we try to inject the script as early as possible.
46
+ for _ , t := range tags {
47
+ idx = bytes . Index ( b , t . markup )
48
+ if idx != - 1 {
49
+ match = t
50
+ break
51
+ }
40
52
}
41
53
42
- if _ , err := ft .To ().Write (newcontent ); err != nil {
54
+ c := make ([]byte , len (b ))
55
+ copy (c , b )
56
+
57
+ if idx == - 1 {
58
+ _ , err := ft .To ().Write (c )
59
+ return err
60
+ }
61
+
62
+ script := []byte (fmt .Sprintf (`<script data-no-instant>document.write('<script src="/livereload.js?port=%d&mindelay=10&v=2"></' + 'script>')</script>` , port ))
63
+
64
+ i := idx
65
+ if match .appendScript {
66
+ i += len (match .markup )
67
+ }
68
+
69
+ c = append (c [:i ], append (script , c [i :]... )... )
70
+
71
+ if _ , err := ft .To ().Write (c ); err != nil {
43
72
helpers .DistinctWarnLog .Println ("Failed to inject LiveReload script:" , err )
44
73
}
45
74
return nil
0 commit comments