eventTracking.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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', [
  59. 'eventTracking',
  60. function (eventTracking) {
  61. return {
  62. scope: {
  63. eventTracking: '@',
  64. eventSegmentation: '=?',
  65. },
  66. link(scope, element, attrs) {
  67. const sendGA = attrs.eventTrackingGa || false
  68. const sendMB = attrs.eventTrackingMb || false
  69. const sendMBFunction = attrs.eventTrackingSendOnce
  70. ? 'sendMBOnce'
  71. : 'sendMB'
  72. const sendGAFunction = attrs.eventTrackingSendOnce
  73. ? 'sendGAOnce'
  74. : 'send'
  75. const segmentation = scope.eventSegmentation || {}
  76. segmentation.page = window.location.pathname
  77. const sendEvent = function (scrollEvent) {
  78. /*
  79. @param {boolean} scrollEvent Use to unbind scroll event
  80. */
  81. if (sendMB) {
  82. eventTracking[sendMBFunction](scope.eventTracking, segmentation)
  83. }
  84. if (sendGA) {
  85. eventTracking[sendGAFunction](
  86. attrs.eventTrackingGa,
  87. attrs.eventTrackingAction || scope.eventTracking,
  88. attrs.eventTrackingLabel || ''
  89. )
  90. }
  91. if (scrollEvent) {
  92. return $(window).unbind('resize scroll')
  93. }
  94. }
  95. if (attrs.eventTrackingTrigger === 'load') {
  96. return sendEvent()
  97. } else if (attrs.eventTrackingTrigger === 'click') {
  98. return element.on('click', e => sendEvent())
  99. } else if (attrs.eventTrackingTrigger === 'hover') {
  100. let timer = null
  101. let timeoutAmt = 500
  102. if (attrs.eventHoverAmt) {
  103. timeoutAmt = parseInt(attrs.eventHoverAmt, 10)
  104. }
  105. return element
  106. .on('mouseenter', function () {
  107. timer = setTimeout(() => sendEvent(), timeoutAmt)
  108. })
  109. .on('mouseleave', () => clearTimeout(timer))
  110. } else if (
  111. attrs.eventTrackingTrigger === 'scroll' &&
  112. !eventTracking.eventInCache(scope.eventTracking)
  113. ) {
  114. $(window).on(
  115. 'resize scroll',
  116. _.throttle(() => {
  117. if (isInViewport(element)) {
  118. sendEvent(true)
  119. }
  120. }, 500)
  121. )
  122. }
  123. },
  124. }
  125. },
  126. ])