Created
March 31, 2018 16:31
-
-
Save panoply/89173f16372ab2c8c1d08c12024d0d2a to your computer and use it in GitHub Desktop.
Prefetching Turbolinks 5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Turbolinks from 'turbolinks'; | |
export default () => { | |
const OldHttpRequest = Turbolinks.HttpRequest; | |
Turbolinks.CachedHttpRequest = class CachedHttpRequest extends Turbolinks.HttpRequest { | |
constructor(_, location, referrer) { | |
super(); | |
super(this, location, referrer); | |
} | |
requestCompletedWithResponse(response, redirectedToLocation) { | |
this.response = response; | |
return(this.redirect = redirectedToLocation); | |
} | |
requestFailedWithStatusCode(code) { | |
return(this.failCode = code); | |
} | |
oldSend() { | |
if (this.xhr && !this.sent) { | |
this.notifyApplicationBeforeRequestStart(); | |
this.setProgress(0); | |
this.xhr.send(); | |
this.sent = true; | |
return(this.delegate, 'requestStarted', o => o.requestStarted()); | |
} | |
} | |
send() { | |
if (this.failCode) { | |
return(this.delegate.requestFailedWithStatusCode(this.failCode, this.failText)); | |
} else if (this.response) { | |
return(this.delegate.requestCompletedWithResponse(this.response, this.redirect)); | |
} else { | |
return(this.oldSend()); | |
} | |
} | |
}; | |
Turbolinks.HttpRequest = class HttpRequest { | |
constructor(delegate, location, referrer) { | |
const cache = Turbolinks.controller.cache.get(`prefetch${location}`); | |
if (cache) { | |
//Turbolinks.controller.cache = new Turbolinks.SnapshotCache 10 | |
Turbolinks.controller.cache.delete(`prefetch${location}`); | |
//console.log(JSON.stringify(Turbolinks.controller.cache.keys)); | |
cache.delegate = delegate; | |
return cache; | |
} else { | |
return(new OldHttpRequest(delegate, location, referrer)); | |
} | |
} | |
}; | |
Turbolinks.SnapshotCache.prototype.delete = function(location) { | |
const key = Turbolinks.Location.wrap(location).toCacheKey(); | |
return(delete this.snapshots[key]); | |
}; | |
const preloadAttribute = function(link) { | |
const linkAttr = link.attributes['data-turbolinks-preload']; | |
if (!linkAttr || linkAttr.value === 'false') { | |
return false; | |
} else { | |
return true; | |
} | |
}; | |
const isNotGetMethod = function(link) { | |
link.attributes['data-method'] && (link.attributes['data-method'].value !== 'get'); | |
}; | |
//This function returns true if the link or location shouldn't be | |
const notPreloadable = function(link, location){ | |
if (preloadAttribute(link) === false) { | |
return true; | |
} else if (isNotGetMethod(link)) { | |
return true; | |
} else if (location.anchor || location.absoluteURL.endsWith("#")) { | |
return true; | |
} else if (location.absoluteURL === window.location.href) { | |
return true; | |
} else { | |
return false; | |
} | |
}; | |
const preload = function(event) { | |
let link = Turbolinks.controller.getVisitableLinkForNode(event.target); | |
if (link) { | |
let location = Turbolinks.controller.getVisitableLocationForLink(link); | |
if (location) { | |
if (Turbolinks.controller.applicationAllowsFollowingLinkToLocation(link, location)) { | |
if (notPreloadable(link, location)) { | |
return; | |
} | |
// If Turbolinks has already cached this location internally, use that default behavior | |
// otherwise we can try and prefetch it here | |
let cache = Turbolinks.controller.cache.get(location); | |
if (!cache) { | |
cache = Turbolinks.controller.cache.get(`prefetch${location}`); | |
} | |
if (!cache) { | |
const request = new Turbolinks.CachedHttpRequest(null, location, window.location); | |
Turbolinks.controller.cache.put(`prefetch${location}`, request); | |
return(request.send()); | |
} | |
} | |
} | |
} | |
}; | |
document.addEventListener("touchstart", preload); | |
document.addEventListener("mouseover", preload); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment