ref: df489b4712dd59b097de0d2fb84cfac7a013f5cd
parent: 0099b5a3cb922ac3f844b5d9d9f098cd1003b0f5
author: bep <bjorn.erik.pedersen@gmail.com>
date: Wed Sep 10 08:21:22 EDT 2014
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
--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -312,10 +312,11 @@
static_changed := false
dynamic_changed := false
+ static_files_changed := make(map[string]bool)
for _, ev := range evs {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 {continue
}
@@ -328,6 +329,12 @@
static_changed = static_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
if s, err := os.Stat(ev.Name); err == nil && s.Mode().IsDir() { if ev.IsCreate() {@@ -342,7 +349,16 @@
if !viper.GetBool("DisableLiveReload") {// 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()
+ }
}
}
--- a/helpers/helpers_test.go
+++ b/helpers/helpers_test.go
@@ -122,3 +122,26 @@
}
}
}
+
+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")+ }
+}
--- a/helpers/path.go
+++ b/helpers/path.go
@@ -14,6 +14,7 @@
package helpers
import (
+ "errors"
"fmt"
"io"
"os"
@@ -128,6 +129,23 @@
}
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) {--- a/livereload/livereload.go
+++ b/livereload/livereload.go
@@ -39,7 +39,12 @@
func ForceRefresh() {// 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) {--
⑨