Skip to content

Instantly share code, notes, and snippets.

@fuunnx
Created September 23, 2019 16:33
Show Gist options
  • Save fuunnx/3a9dd9e6a1b9b39a15c86dd6d08b75d2 to your computer and use it in GitHub Desktop.
Save fuunnx/3a9dd9e6a1b9b39a15c86dd6d08b75d2 to your computer and use it in GitHub Desktop.
fork from captureClicks from @cycle/history, with shadow dom support (you may need a polyfill for `event.composedPath()`)
export function captureClicks(callback) {
const listener = makeClickListener(callback)
if (typeof window !== 'undefined') {
document.addEventListener('click', listener, false)
}
return () => {
document.removeEventListener('click', listener)
}
}
function which(ev) {
if (typeof window === 'undefined') {
return false
}
const e = ev || window.event
return e.which === null ? e.button : e.which
}
function sameOrigin(href) {
if (typeof window === 'undefined') {
return false
}
return href && href.indexOf(window.location.origin) === 0
}
function makeClickListener(callback) {
return function clickListener(event) {
if (which(event) !== 1) {
return
}
if (event.metaKey || event.ctrlKey || event.shiftKey) {
return
}
if (event.defaultPrevented) {
return
}
const eventPath = event.composedPath()
let element = null
for (let i = 0; i < eventPath.length; i++) {
const checking = eventPath[i]
if (checking.tagName === 'A' && checking.href) {
element = checking
break
}
}
if (!element || element.nodeName !== 'A') {
return
}
if (
element.hasAttribute('download') ||
element.getAttribute('rel') === 'external'
) {
return
}
if (element.target) {
return
}
const link = element.getAttribute('href')
if ((link && link.indexOf('mailto:') > -1) || link.charAt(0) === '#') {
return
}
if (!sameOrigin(element.href)) {
return
}
event.preventDefault()
const {search, hash = ''} = element
callback({ event, element, url: link, search, hash })
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment