Merge pull request #5116 from overleaf/jpa-event-tracking-de-ng

[web] event-tracking: implement sprinkle using the ng attributes

GitOrigin-RevId: 5195d827b590ee32e86ba2ffe365ad7cab65750b
This commit is contained in:
Jakob Ackermann 2021-09-16 17:18:16 +02:00 committed by Copybot
parent 4ee76cf2b4
commit 94a46c3c40
3 changed files with 97 additions and 14 deletions

View file

@ -0,0 +1,75 @@
import _ from 'lodash'
import * as eventTracking from '../../infrastructure/event-tracking'
function isInViewport(element) {
const elTop = $(element).offset().top
const elBtm = elTop + $(element).outerHeight()
const viewportTop = $(window).scrollTop()
const viewportBtm = viewportTop + $(window).height()
return elBtm > viewportTop && elTop < viewportBtm
}
function setupEventTracking(el) {
const key = el.getAttribute('event-tracking')
const action = el.getAttribute('event-tracking-action') || key
const label = el.getAttribute('event-tracking-label') || ''
const gaCategory = el.getAttribute('event-tracking-ga')
const sendMB = el.getAttribute('event-tracking-mb')
const trigger = el.getAttribute('event-tracking-trigger')
const sendOnce = el.getAttribute('event-tracking-send-once')
const segmentation = JSON.parse(el.getAttribute('event-segmentation') || '{}')
segmentation.page = window.location.pathname
function submit() {
if (sendMB) {
if (sendOnce) {
eventTracking.sendMBOnce(key, segmentation)
} else {
eventTracking.sendMB(key, segmentation)
}
}
if (gaCategory) {
if (sendOnce) {
eventTracking.sendOnce(gaCategory, action, label)
} else {
eventTracking.send(gaCategory, action, label)
}
}
}
let handler
let timer
let timeoutAmt = 500
switch (trigger) {
case 'load':
submit()
break
case 'click':
el.addEventListener('click', () => submit())
break
case 'hover':
if (el.getAttribute('event-hover-amt')) {
timeoutAmt = parseInt(el.getAttribute('event-hover-amt'), 10)
}
el.addEventListener('mouseenter', () => {
timer = setTimeout(() => submit(), timeoutAmt)
})
el.addEventListener('mouseleave', () => clearTimeout(timer))
break
case 'scroll':
handler = _.throttle(() => {
if (isInViewport(el)) {
submit()
window.removeEventListener('scroll', handler)
window.removeEventListener('resize', handler)
}
}, 500)
window.addEventListener('scroll', handler)
window.addEventListener('resize', handler)
break
}
}
document.querySelectorAll('[event-tracking]').forEach(setupEventTracking)

View file

@ -2,31 +2,38 @@ import sessionStorage from '../infrastructure/session-storage'
const CACHE_KEY = 'mbEvents'
function alreadySent(key) {
const eventCache = sessionStorage.getItem(CACHE_KEY) || {}
return !!eventCache[key]
}
function markAsSent(key) {
const eventCache = sessionStorage.getItem(CACHE_KEY) || {}
eventCache[key] = true
sessionStorage.setItem(CACHE_KEY, eventCache)
}
export function send(category, action, label, value) {
if (typeof window.ga === 'function') {
window.ga('send', 'event', category, action, label, value)
}
}
export function sendOnce(category, action, label, value) {
if (alreadySent(category)) return
if (typeof window.ga !== 'function') return
window.ga('send', 'event', category, action, label, value)
markAsSent(category)
}
export function sendMB(key, segmentation = {}) {
sendBeacon(key, segmentation)
}
export function sendMBOnce(key, segmentation = {}) {
let eventCache = sessionStorage.getItem(CACHE_KEY)
// Initialize as an empy object if the event cache is still empty.
if (eventCache == null) {
eventCache = {}
sessionStorage.setItem(CACHE_KEY, eventCache)
}
const isEventInCache = eventCache[key] || false
if (!isEventInCache) {
eventCache[key] = true
sessionStorage.setItem(CACHE_KEY, eventCache)
sendMB(key, segmentation)
}
if (alreadySent(key)) return
sendMB(key, segmentation)
markAsSent()
}
export function sendMBSampled(key, body = {}, rate = 0.01) {

View file

@ -3,5 +3,6 @@ import 'jquery'
import 'bootstrap'
import './features/form-helpers/hydrate-form'
import './features/contact-form'
import './features/event-tracking'
$('[data-ol-lang-selector-tooltip]').tooltip({ trigger: 'hover' })