From: Bjørn Erik Pedersen Date: Wed, 29 Jan 2020 11:46:18 +0000 (+0100) Subject: transform/livereloadinject: Inject livereload script right after head if possible X-Git-Tag: v0.64.0~14 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=8f08cdd0ac6a2decd5aa5c9c12c0b2c264f9a989;p=brevno-suite%2Fhugo transform/livereloadinject: Inject livereload script right after head if possible We used to insert the livereload script right before the closing body. This dord not work when combined with tools such as Turbolinks. This commit changes it So we try to inject the script as early as possible. Fixes #6821 --- diff --git a/transform/livereloadinject/livereloadinject.go b/transform/livereloadinject/livereloadinject.go index bee40f25..f34b4fb5 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(""), appendScript: true}, + tag{markup: []byte(""), appendScript: true}, + tag{markup: []byte("")}, + tag{markup: []byte("")}, +} + // 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 := "" - match := []byte(endBodyTag) - replaceTemplate := `%s` - replace := []byte(fmt.Sprintf(replaceTemplate, port, endBodyTag)) - - newcontent := bytes.Replace(b, match, replace, 1) - if len(newcontent) == len(b) { - endBodyTag = "" - 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(``, 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 diff --git a/transform/livereloadinject/livereloadinject_test.go b/transform/livereloadinject/livereloadinject_test.go index 413ca7b4..4dd256bb 100644 --- a/transform/livereloadinject/livereloadinject_test.go +++ b/transform/livereloadinject/livereloadinject_test.go @@ -15,27 +15,45 @@ package livereloadinject import ( "bytes" - "fmt" "strings" "testing" + qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/transform" ) func TestLiveReloadInject(t *testing.T) { - doTestLiveReloadInject(t, "") - doTestLiveReloadInject(t, "") -} + c := qt.New(t) -func doTestLiveReloadInject(t *testing.T, bodyEndTag string) { - out := new(bytes.Buffer) - in := strings.NewReader(bodyEndTag) + expectBase := `` + apply := func(s string) string { + out := new(bytes.Buffer) + in := strings.NewReader(s) - tr := transform.New(New(1313)) - tr.Apply(out, in) + tr := transform.New(New(1313)) + tr.Apply(out, in) - expected := fmt.Sprintf(`%s`, bodyEndTag) - if out.String() != expected { - t.Errorf("Expected %s got %s", expected, out.String()) + return out.String() } + + c.Run("Head lower", func(c *qt.C) { + c.Assert(apply("foo"), qt.Equals, ""+expectBase+"foo") + }) + + c.Run("Head upper", func(c *qt.C) { + c.Assert(apply("foo"), qt.Equals, ""+expectBase+"foo") + }) + + c.Run("Body lower", func(c *qt.C) { + c.Assert(apply("foo"), qt.Equals, "foo"+expectBase+"") + }) + + c.Run("Body upper", func(c *qt.C) { + c.Assert(apply("foo"), qt.Equals, "foo"+expectBase+"") + }) + + c.Run("No match", func(c *qt.C) { + c.Assert(apply("

No match

"), qt.Equals, "

No match

") + }) + }