eventTracking.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import _ from 'lodash'
  2. /* eslint-disable
  3. camelcase,
  4. max-len,
  5. */
  6. // TODO: This file was created by bulk-decaffeinate.
  7. // Fix any style issues and re-enable lint.
  8. /*
  9. * decaffeinate suggestions:
  10. * DS102: Remove unnecessary code created because of implicit returns
  11. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  12. */
  13. // For sending event data to metabase and google analytics
  14. // ---
  15. // by default,
  16. // event not sent to MB.
  17. // for MB, add event-tracking-mb='true'
  18. // by default, event sent to MB via sendMB
  19. // event not sent to GA.
  20. // for GA, add event-tracking-ga attribute, where the value is the GA category
  21. // Either GA or MB can use the attribute event-tracking-send-once='true' to
  22. // send event just once
  23. // MB will use the key and GA will use the action to determine if the event
  24. // has been sent
  25. // event-tracking-trigger attribute is required to send event
  26. /* eslint-disable
  27. camelcase,
  28. max-len,
  29. */
  30. // TODO: This file was created by bulk-decaffeinate.
  31. // Fix any style issues and re-enable lint.
  32. /*
  33. * decaffeinate suggestions:
  34. * DS102: Remove unnecessary code created because of implicit returns
  35. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  36. */
  37. // For sending event data to metabase and google analytics
  38. // ---
  39. // by default,
  40. // event not sent to MB.
  41. // for MB, add event-tracking-mb='true'
  42. // by default, event sent to MB via sendMB
  43. // event not sent to GA.
  44. // for GA, add event-tracking-ga attribute, where the value is the GA category
  45. // Either GA or MB can use the attribute event-tracking-send-once='true' to
  46. // send event just once
  47. // MB will use the key and GA will use the action to determine if the event
  48. // has been sent
  49. // event-tracking-trigger attribute is required to send event
  50. import App from '../base'
  51. const isInViewport = function(element) {
  52. const elTop = element.offset().top
  53. const elBtm = elTop + element.outerHeight()
  54. const viewportTop = $(window).scrollTop()
  55. const viewportBtm = viewportTop + $(window).height()
  56. return elBtm > viewportTop && elTop < viewportBtm
  57. }
  58. export default App.directive('eventTracking', eventTracking => ({
  59. scope: {
  60. eventTracking: '@',
  61. eventSegmentation: '=?'
  62. },
  63. link(scope, element, attrs) {
  64. const sendGA = attrs.eventTrackingGa || false
  65. const sendMB = attrs.eventTrackingMb || false
  66. const sendMBFunction = attrs.eventTrackingSendOnce ? 'sendMBOnce' : 'sendMB'
  67. const sendGAFunction = attrs.eventTrackingSendOnce ? 'sendGAOnce' : 'send'
  68. const segmentation = scope.eventSegmentation || {}
  69. segmentation.page = window.location.pathname
  70. const sendEvent = function(scrollEvent) {
  71. /*
  72. @param {boolean} scrollEvent Use to unbind scroll event
  73. */
  74. if (sendMB) {
  75. eventTracking[sendMBFunction](scope.eventTracking, segmentation)
  76. }
  77. if (sendGA) {
  78. eventTracking[sendGAFunction](
  79. attrs.eventTrackingGa,
  80. attrs.eventTrackingAction || scope.eventTracking,
  81. attrs.eventTrackingLabel || ''
  82. )
  83. }
  84. if (scrollEvent) {
  85. return $(window).unbind('resize scroll')
  86. }
  87. }
  88. if (attrs.eventTrackingTrigger === 'load') {
  89. return sendEvent()
  90. } else if (attrs.eventTrackingTrigger === 'click') {
  91. return element.on('click', e => sendEvent())
  92. } else if (attrs.eventTrackingTrigger === 'hover') {
  93. let timer = null
  94. let timeoutAmt = 500
  95. if (attrs.eventHoverAmt) {
  96. timeoutAmt = parseInt(attrs.eventHoverAmt, 10)
  97. }
  98. return element
  99. .on('mouseenter', function() {
  100. timer = setTimeout(() => sendEvent(), timeoutAmt)
  101. })
  102. .on('mouseleave', () => clearTimeout(timer))
  103. } else if (
  104. attrs.eventTrackingTrigger === 'scroll' &&
  105. !eventTracking.eventInCache(scope.eventTracking)
  106. ) {
  107. $(window).on(
  108. 'resize scroll',
  109. _.throttle(() => {
  110. if (isInViewport(element)) {
  111. sendEvent(true)
  112. }
  113. }, 500)
  114. )
  115. }
  116. }
  117. }))