mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
Enable soft livereload of CSS and images
Prior to this commit a dummy JavaScript filename was sent to LiveReload when changing a static file (CSS, image etc.), forcing a full browser reload of the page. This commit fixes this by sending the relative file path of the changed static resource, enabling partial live reloading for CSS- and image-changes. If more than one static file happens to end up in the same changeevent-batch, it will fall back to do a full refresh. To enable this logic, the change events with names ending with ".goutputstream*" is now filtered out as temporary. Changes in dynamic content behaves like before. Issue #490
This commit is contained in:
parent
0099b5a3cb
commit
df489b4712
4 changed files with 65 additions and 3 deletions
|
@ -312,10 +312,11 @@ func NewWatcher(port int) error {
|
||||||
|
|
||||||
static_changed := false
|
static_changed := false
|
||||||
dynamic_changed := false
|
dynamic_changed := false
|
||||||
|
static_files_changed := make(map[string]bool)
|
||||||
|
|
||||||
for _, ev := range evs {
|
for _, ev := range evs {
|
||||||
ext := filepath.Ext(ev.Name)
|
ext := filepath.Ext(ev.Name)
|
||||||
istemp := strings.HasSuffix(ext, "~") || (ext == ".swp") || (ext == ".tmp")
|
istemp := strings.HasSuffix(ext, "~") || (ext == ".swp") || (ext == ".tmp") || (strings.HasPrefix(ext, ".goutputstream"))
|
||||||
if istemp {
|
if istemp {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -328,6 +329,12 @@ func NewWatcher(port int) error {
|
||||||
static_changed = static_changed || isstatic
|
static_changed = static_changed || isstatic
|
||||||
dynamic_changed = dynamic_changed || !isstatic
|
dynamic_changed = dynamic_changed || !isstatic
|
||||||
|
|
||||||
|
if isstatic {
|
||||||
|
if staticPath, err := helpers.MakeStaticPathRelative(ev.Name); err == nil {
|
||||||
|
static_files_changed[staticPath] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add new directory to watch list
|
// add new directory to watch list
|
||||||
if s, err := os.Stat(ev.Name); err == nil && s.Mode().IsDir() {
|
if s, err := os.Stat(ev.Name); err == nil && s.Mode().IsDir() {
|
||||||
if ev.IsCreate() {
|
if ev.IsCreate() {
|
||||||
|
@ -342,7 +349,16 @@ func NewWatcher(port int) error {
|
||||||
|
|
||||||
if !viper.GetBool("DisableLiveReload") {
|
if !viper.GetBool("DisableLiveReload") {
|
||||||
// Will block forever trying to write to a channel that nobody is reading if livereload isn't initalized
|
// Will block forever trying to write to a channel that nobody is reading if livereload isn't initalized
|
||||||
livereload.ForceRefresh()
|
|
||||||
|
// force refresh when more than one file
|
||||||
|
if len(static_files_changed) == 1 {
|
||||||
|
for path := range static_files_changed {
|
||||||
|
livereload.RefreshPath(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
livereload.ForceRefresh()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,3 +122,26 @@ func TestMakePermalink(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMakePathRelative(t *testing.T) {
|
||||||
|
type test struct {
|
||||||
|
inPath, path1, path2, output string
|
||||||
|
}
|
||||||
|
|
||||||
|
data := []test{
|
||||||
|
{"/abc/bcd/ab.css", "/abc/bcd", "/bbc/bcd", "/ab.css"},
|
||||||
|
{"/abc/bcd/ab.css", "/abcd/bcd", "/abc/bcd", "/ab.css"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, d := range data {
|
||||||
|
output, _ := MakePathRelative(d.inPath, d.path1, d.path2)
|
||||||
|
if d.output != output {
|
||||||
|
t.Errorf("Test #%d failed. Expected %q got %q", i, d.output, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, error := MakePathRelative("a/b/c.ss", "/a/c", "/d/c", "/e/f")
|
||||||
|
|
||||||
|
if error == nil {
|
||||||
|
t.Errorf("Test #%d failed. Expected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
package helpers
|
package helpers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -130,6 +131,23 @@ func AbsPathify(inPath string) string {
|
||||||
return filepath.Clean(filepath.Join(viper.GetString("WorkingDir"), inPath))
|
return filepath.Clean(filepath.Join(viper.GetString("WorkingDir"), inPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MakeStaticPathRelative(inPath string) (string, error) {
|
||||||
|
staticDir := AbsPathify(viper.GetString("StaticDir"))
|
||||||
|
themeStaticDir := AbsPathify("themes/"+viper.GetString("theme")) + "/static/"
|
||||||
|
|
||||||
|
return MakePathRelative(inPath, staticDir, themeStaticDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakePathRelative(inPath string, possibleDirectories ...string) (string, error) {
|
||||||
|
|
||||||
|
for _, currentPath := range possibleDirectories {
|
||||||
|
if strings.HasPrefix(inPath, currentPath) {
|
||||||
|
return strings.TrimPrefix(inPath, currentPath), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inPath, errors.New("Can't extract relative path, unknown prefix")
|
||||||
|
}
|
||||||
|
|
||||||
func Filename(in string) (name string) {
|
func Filename(in string) (name string) {
|
||||||
name, _ = FileAndExt(in)
|
name, _ = FileAndExt(in)
|
||||||
return
|
return
|
||||||
|
|
|
@ -39,7 +39,12 @@ func Initialize() {
|
||||||
|
|
||||||
func ForceRefresh() {
|
func ForceRefresh() {
|
||||||
// Tell livereload a js file changed to force a hard refresh
|
// Tell livereload a js file changed to force a hard refresh
|
||||||
wsHub.broadcast <- []byte(`{"command":"reload","path":"/x.js","originalPath":"","liveCSS":true}`)
|
RefreshPath("/x.js")
|
||||||
|
}
|
||||||
|
|
||||||
|
func RefreshPath(s string) {
|
||||||
|
// Tell livereload a file has changed - will force a hard refresh if not CSS or an image
|
||||||
|
wsHub.broadcast <- []byte(`{"command":"reload","path":"` + s + "\"" + `,"originalPath":"","liveCSS":true,"liveImg":true}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ServeJS(w http.ResponseWriter, r *http.Request) {
|
func ServeJS(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
Loading…
Reference in a new issue