summaryrefslogtreecommitdiffstats
path: root/transform/livereloadinject/livereloadinject.go
diff options
context:
space:
mode:
Diffstat (limited to 'transform/livereloadinject/livereloadinject.go')
-rw-r--r--transform/livereloadinject/livereloadinject.go53
1 files changed, 41 insertions, 12 deletions
diff --git a/transform/livereloadinject/livereloadinject.go b/transform/livereloadinject/livereloadinject.go
index bee40f25c..f34b4fb59 100644
--- a/transform/livereloadinject/livereloadinject.go
+++ b/transform/livereloadinject/livereloadinject.go
@@ -21,25 +21,54 @@ import (
"github.com/gohugoio/hugo/transform"
)
+type tag struct {
+ markup []byte
+ appendScript bool
+}
+
+var tags = []tag{
+ tag{markup: []byte("<head>"), appendScript: true},
+ tag{markup: []byte("<HEAD>"), appendScript: true},
+ tag{markup: []byte("</body>")},
+ tag{markup: []byte("</BODY>")},
+}
+
// New creates a function that can be used
// to inject a script tag for the livereload JavaScript in a HTML document.
func New(port int) transform.Transformer {
return func(ft transform.FromTo) error {
b := ft.From().Bytes()
- endBodyTag := "</body>"
- match := []byte(endBodyTag)
- replaceTemplate := `<script data-no-instant>document.write('<script src="/livereload.js?port=%d&mindelay=10&v=2"></' + 'script>')</script>%s`
- replace := []byte(fmt.Sprintf(replaceTemplate, port, endBodyTag))
-
- newcontent := bytes.Replace(b, match, replace, 1)
- if len(newcontent) == len(b) {
- endBodyTag = "</BODY>"
- replace := []byte(fmt.Sprintf(replaceTemplate, port, endBodyTag))
- match := []byte(endBodyTag)
- newcontent = bytes.Replace(b, match, replace, 1)
+ var idx = -1
+ var match tag
+ // We used to insert the livereload script right before the closing body.
+ // This does not work when combined with tools such as Turbolinks.
+ // So we try to inject the script as early as possible.
+ for _, t := range tags {
+ idx = bytes.Index(b, t.markup)
+ if idx != -1 {
+ match = t
+ break
+ }
}
- if _, err := ft.To().Write(newcontent); err != nil {
+ c := make([]byte, len(b))
+ copy(c, b)
+
+ if idx == -1 {
+ _, err := ft.To().Write(c)
+ return err
+ }
+
+ script := []byte(fmt.Sprintf(`<script data-no-instant>document.write('<script src="/livereload.js?port=%d&mindelay=10&v=2"></' + 'script>')</script>`, port))
+
+ i := idx
+ if match.appendScript {
+ i += len(match.markup)
+ }
+
+ c = append(c[:i], append(script, c[i:]...)...)
+
+ if _, err := ft.To().Write(c); err != nil {
helpers.DistinctWarnLog.Println("Failed to inject LiveReload script:", err)
}
return nil