71 lines
1.7 KiB
TypeScript
71 lines
1.7 KiB
TypeScript
import { History, Location } from 'history'
|
|
import { debounce, inIframe } from './utils'
|
|
|
|
declare global {
|
|
interface Window {
|
|
_paq: any
|
|
}
|
|
}
|
|
|
|
type PushArgs = ['trackPageView'] | ['trackEvent', ...Array<string | number>]
|
|
type PushType = (args: PushArgs) => void
|
|
|
|
const ua = window.navigator.userAgent
|
|
// https://chromium.googlesource.com/chromium/src.git/+/master/docs/ios/user_agent.md
|
|
const iOSSafari =
|
|
(!!ua.match(/iPad/i) || !!ua.match(/iPhone/i)) &&
|
|
!!ua.match(/WebKit/i) &&
|
|
!ua.match(/CriOS/i)
|
|
|
|
export default class Tracker {
|
|
push: PushType
|
|
unlistenFromHistory: (() => void) | undefined
|
|
previousPath: string | undefined
|
|
|
|
constructor(
|
|
pushFunction: PushType = args => {
|
|
// There is an issue with the way Safari handle cookies in iframe, cf.
|
|
// https://gist.github.com/iansltx/18caf551baaa60b79206. We could probably
|
|
// do better but for now we don't track action of iOs Safari user in
|
|
// iFrame -- to avoid errors in the number of visitors in our stats.
|
|
if (!(iOSSafari && inIframe)) {
|
|
window._paq.push(args)
|
|
}
|
|
}
|
|
) {
|
|
if (typeof window !== 'undefined') window._paq = window._paq || []
|
|
this.push = debounce(200, pushFunction) as PushType
|
|
}
|
|
|
|
connectToHistory(history: History) {
|
|
this.unlistenFromHistory = history.listen(loc => {
|
|
this.track(loc)
|
|
})
|
|
|
|
return history
|
|
}
|
|
|
|
disconnectFromHistory() {
|
|
if (this.unlistenFromHistory) {
|
|
this.unlistenFromHistory()
|
|
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
track(loc: Location) {
|
|
const currentPath = loc.pathname + loc.search
|
|
|
|
if (this.previousPath === currentPath) {
|
|
return
|
|
}
|
|
this.push(['trackPageView'])
|
|
this.previousPath = currentPath
|
|
}
|
|
}
|
|
|
|
export const devTracker = new Tracker(
|
|
console?.debug?.bind(console) ?? (() => {}) // eslint-disable-line no-console
|
|
)
|