Open steffenweber opened 6 years ago
Sounds reasonable to me. There is no way the server can be aware of how to transform this, right?
The server (gulp + tiny-lr in my case) could compute the new digest/hash but it does not know the old digest/hash. However, it could provide the client with a regex to transform the path if you'd prefer making this configurable in the server instead of in window.LiveReloadOptions
.
The following patch adds a client-side option pathRewriteFn
that is handled inside pathFromUrl
. I had to move this function into the Reloader
class such that it has access to the @options
object. I've furthermore renamed the old @options
object to @reloadOptions
(such that @options
refers to the same object as in other source files).
diff --git a/src/livereload.coffee b/src/livereload.coffee
index 06f2579..0073400 100644
--- a/src/livereload.coffee
+++ b/src/livereload.coffee
@@ -40,7 +40,7 @@ exports.LiveReload = class LiveReload
return
# i can haz reloader?
- @reloader = new Reloader(@window, @console, Timer)
+ @reloader = new Reloader(@options, @window, @console, Timer)
# i can haz connection?
@connector = new Connector @options, @WebSocket, Timer,
diff --git a/src/options.coffee b/src/options.coffee
index 057ba30..2cb7393 100644
--- a/src/options.coffee
+++ b/src/options.coffee
@@ -12,6 +12,8 @@ exports.Options = class Options
@maxdelay = 60000
@handshake_timeout = 5000
+ @pathRewriteFn = null
+
set: (name, value) ->
if typeof value is 'undefined'
return
diff --git a/src/reloader.coffee b/src/reloader.coffee
index 4df0a52..56de2b0 100644
--- a/src/reloader.coffee
+++ b/src/reloader.coffee
@@ -20,17 +20,6 @@ splitUrl = (url) ->
return { url, params, hash }
-pathFromUrl = (url) ->
- url = splitUrl(url).url
- if url.indexOf('file://') == 0
- path = url.replace ///^ file:// (localhost)? ///, ''
- else
- # http : // hostname :8080 /
- path = url.replace ///^ ([^:]+ :)? // ([^:/]+) (:\d*)? / ///, '/'
-
- # decodeURI has special handling of stuff like semicolons, so use decodeURIComponent
- return decodeURIComponent(path)
-
pickBestMatch = (path, objects, pathFunc) ->
bestMatch = { score: 0 }
for object in objects
@@ -68,7 +57,7 @@ IMAGE_STYLES = [
exports.Reloader = class Reloader
- constructor: (@window, @console, @Timer) ->
+ constructor: (@options, @window, @console, @Timer) ->
@document = @window.document
@importCacheWaitPeriod = 200
@plugins = []
@@ -83,8 +72,8 @@ exports.Reloader = class Reloader
reload: (path, options) ->
- @options = options # avoid passing it through all the funcs
- @options.stylesheetReloadTimeout ?= 15000
+ @reloadOptions = options # avoid passing it through all the funcs
+ @reloadOptions.stylesheetReloadTimeout ?= 15000
for plugin in @plugins
if plugin.reload && plugin.reload(path, options)
return
@@ -109,7 +98,7 @@ exports.Reloader = class Reloader
expando = @generateUniqueString()
for img in this.document.images
- if pathsMatch(path, pathFromUrl(img.src))
+ if pathsMatch(path, @pathFromUrl(img.src))
img.src = @generateCacheBustUrl(img.src, expando)
if @document.querySelectorAll
@@ -147,7 +136,7 @@ exports.Reloader = class Reloader
value = style[styleName]
if typeof value is 'string'
newValue = value.replace ///\b url \s* \( ([^)]*) \) ///, (match, src) =>
- if pathsMatch(path, pathFromUrl(src))
+ if pathsMatch(path, @pathFromUrl(src))
"url(#{@generateCacheBustUrl(src, expando)})"
else
match
@@ -173,7 +162,7 @@ exports.Reloader = class Reloader
links.push style
@console.log "LiveReload found #{links.length} LINKed stylesheets, #{imported.length} @imported stylesheets"
- match = pickBestMatch(path, links.concat(imported), (l) => pathFromUrl(@linkHref(l)))
+ match = pickBestMatch(path, links.concat(imported), (l) => @pathFromUrl(@linkHref(l)))
if match
if match.object.rule
@@ -241,7 +230,7 @@ exports.Reloader = class Reloader
@Timer.start 50, poll
# fail safe
- @Timer.start @options.stylesheetReloadTimeout, executeCallback
+ @Timer.start @reloadOptions.stylesheetReloadTimeout, executeCallback
linkHref: (link) ->
@@ -335,10 +324,10 @@ exports.Reloader = class Reloader
generateCacheBustUrl: (url, expando=@generateUniqueString()) ->
{ url, hash, params: oldParams } = splitUrl(url)
- if @options.overrideURL
- if url.indexOf(@options.serverURL) < 0
+ if @reloadOptions.overrideURL
+ if url.indexOf(@reloadOptions.serverURL) < 0
originalUrl = url
- url = @options.serverURL + @options.overrideURL + "?url=" + encodeURIComponent(url)
+ url = @reloadOptions.serverURL + @reloadOptions.overrideURL + "?url=" + encodeURIComponent(url)
@console.log "LiveReload is overriding source URL #{originalUrl} with #{url}"
params = oldParams.replace /(\?|&)livereload=(\d+)/, (match, sep) -> "#{sep}#{expando}"
@@ -349,3 +338,19 @@ exports.Reloader = class Reloader
params = "#{oldParams}&#{expando}"
return url + params + hash
+
+ pathFromUrl: (url) ->
+ url = splitUrl(url).url
+ if url.indexOf('file://') == 0
+ path = url.replace ///^ file:// (localhost)? ///, ''
+ else
+ # http : // hostname :8080 /
+ path = url.replace ///^ ([^:]+ :)? // ([^:/]+) (:\d*)? / ///, '/'
+
+ # decodeURI has special handling of stuff like semicolons, so use decodeURIComponent
+ path = decodeURIComponent(path)
+
+ if typeof @options.pathRewriteFn == 'function'
+ path = @options.pathRewriteFn(path)
+
+ return path
Example usage:
window.LiveReloadOptions = {
host: 'localhost',
pathRewriteFn: function(path) {
return path.replace(/\.[0-9a-f]{8}\./, '.');
}
};
What do you think?
First of all, thank you for implementing issue #17!
My asset hrefs contain a digest/hash, i.e. the
main.css
on disk is referenced asmain.eec09356.css
in the HTML (which is then rewritten tomain.css
by the webserver). The "changed" URL sent to livereload-js is justmain.css
. Therefore nothing matches withreloadMissingCSS = false
.I think I'd have to modify the
pathFromUrl
function to support this setup:path = path.replace(/\.[0-9a-f]{8}\./, '.');
What would be the best way to make this feature optional / configurable such that it can be merged? Maybe a new
pathFromUrl
option that (if present) would be used instead of the defaultpathFromUrl
function?