Skip to content

Instantly share code, notes, and snippets.

@johndwells
Created June 5, 2020 17:06
Show Gist options
  • Save johndwells/6f011380d8a36d39b03a73c9a246e3ee to your computer and use it in GitHub Desktop.
Save johndwells/6f011380d8a36d39b03a73c9a246e3ee to your computer and use it in GitHub Desktop.
Automatically pass all same-domain links through unpoly.js
// Automatically bind internal links to `up-follow` behaviour
// Unpoly will already catch and handle links with explicit `up-follow` etc,
// so we are safe to assume that if our handler below is triggered, the link
// doesn't already have an up- attribute.
//
// Scenarios to handle:
// Hat-tip to https://github.com/instantpage/instant.page/blob/master/instantpage.js
// ✅ cmd+click
// ✅ empty links
// ✅ links to another domain
// ✅ links to non-http|s protocol
// ✅ links to http from https
// ✅ links with anchors to existing page
// ✅ links with `download` attribute
// ✅ links with `target` attribute that is not equal to `_self`
// ✅ links to non-html (in our case, we can just assume ANY extension should be skipped)
// ✅ specifically disabled via `data-up="false"`
//
// Roadmap / potential to-dos:
// - blacklist certain urls/patterns
// - whitelist extensions
// - enable up-instant
up.on('click', 'a', function(event, element) {
up.log.debug('Attempting to automatically up-follow');
const location = window.location;
if(event.which > 1 || event.metaKey || event.ctrlKey) {
up.log.debug('Skipping: cmd+click');
return;
}
if( ! element.href) {
up.log.debug('Skipping: non-existent href attribute');
return;
}
if(element.origin != location.origin) {
up.log.debug('Skipping: external domain');
return;
}
if( ! ['http:', 'https:'].includes(element.protocol)) {
up.log.debug('Skipping: non http|s protocol');
return;
}
if(element.protocol == 'http:' && location.protocol == 'https:') {
up.log.debug('Skipping: from https to http');
return;
}
if(element.hash && element.pathname + element.search == location.pathname + location.search) {
up.log.debug('Skipping: anchor link to same page');
return;
}
if(element.getAttribute('download') !== null) {
up.log.debug('Skipping: download attribute is present');
return;
}
if(element.target && element.target.toLowerCase() !== '_self') {
up.log.debug('Skipping: target attribute is present and not `_self`');
return;
}
if(element.pathname.split('/').pop().indexOf('.') > -1) {
up.log.debug('Skipping: file extension detected');
return;
}
if('up' in element.dataset && element.dataset.up == 'false') {
up.log.debug('Skipping: disabled via `data-up="false"`');
return;
}
up.log.debug('Automatically up-following');
event.preventDefault();
up.follow(element);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment