Commit 2129c69f by James Ooi

Add ability to override send event function

parent 370a70de
# Foresight
### Foresight is an analytics library that allows for declarative event tracking in your websites.
### Foresight is an analytics library that allows for declarative event tracking.
* Lightweight (<3kb minified and gzipped)
* Declarative event tracking
......@@ -9,7 +9,7 @@
### Direct download
Download and install the latest distribution file from this
Git repository and load it in your webpage. For production cases, we encourage you to download the minified version ([`foresight.min.js`](#))
Git repository and load it in your webpage. For production cases, we encourage you to download the minified version ([`foresight.min.js`](blob/master/dist/foresight.min.js))
```html
<script src="/path/to/foresight.min.js"></script>
......@@ -94,19 +94,19 @@ The above markup would send the following event data when the `div` enters the v
## Configuration
```ts
```js
{
/** Defer tracking initialisation. */
defer?: boolean
defer: false
/** Configure the intersection observer. */
observerOptions?: IntersectionObserverConfig
observerOptions: { /* Refer to Intersection Observer documentation */ }
/** Treat clicks as an interactive event. Defaults to `true`. */
clicksAreInteractions?: boolean
clicksAreInteractions: true
/** Treat views as an interactive event. Defaults to `false`. */
viewsAreInteractions?: boolean
viewsAreInteractions: false
}
```
......@@ -140,4 +140,16 @@ Parameters:
---
#### `send(data: EventData)`
Manually send an analytics event data.
Parameters:
* `data: EventData` An object containing the event data with the following keys:
* `category: string`
* `action: string`
* `label: string`
* `interaction: boolean`
---
Copyright © 2018 FOREFRONT International Sdn Bhd.
\ No newline at end of file
......@@ -121,8 +121,7 @@ var __assign = (this && this.__assign) || function () {
__webpack_require__(1);
var Utils = __webpack_require__(2);
/**
* Foresight is an analytics library that allows for declarative event tracking
* in your websites.
* Foresight is an analytics library that allows for declarative event tracking.
* @class
*/
var Foresight = /** @class */ (function () {
......@@ -130,6 +129,7 @@ var Foresight = /** @class */ (function () {
* @constructor
*/
function Foresight(config) {
if (config === void 0) { config = {}; }
var _this = this;
/**
* Stores a mapping of elements with is respective functions to de-register
......@@ -158,20 +158,18 @@ var Foresight = /** @class */ (function () {
}
}
/**
* Start event tracking for all DOM elements with event tracking attributes.
* Start tracking all elements with tracking attributes for events.
* @param {Element} root The container to scan for elements. Defaults to `body`.
*/
Foresight.prototype.start = function (root) {
var _this = this;
if (root === void 0) { root = document.body; }
if (gtag === undefined) {
throw "The 'gtag' function is undefined. Has Google Analytics been loaded yet?";
}
Utils
.toArray(root.querySelectorAll('[data-track], [data-track-view]'))
.map(function (element) { return _this.track(element); });
};
/**
* Enables event tracking for a DOM element with event tracking attribute.
* Start tracking an element for events.
*/
Foresight.prototype.track = function (element) {
if (!this._untrackFns.has(element)) {
......@@ -193,7 +191,7 @@ var Foresight = /** @class */ (function () {
this._untrackFns.set(element, untrackFn);
};
/**
* Disable event tracking for a DOM element.
* Stop tracking an element for events.
*/
Foresight.prototype.untrack = function (element) {
var untrackFn = this._untrackFns.get(element);
......@@ -209,6 +207,31 @@ var Foresight = /** @class */ (function () {
this._untrackFns.delete(element);
};
/**
* Manually send an analytics event data.
*/
Foresight.prototype.send = function (data) {
if (this.options.sendEventFn !== null) {
return this.options.sendEventFn(data);
}
if (typeof window['gtag'] === 'function') {
return window['gtag']('event', data.action, {
'event_label': data.label,
'event_category': data.category,
'non_interaction': !data.interaction,
});
}
if (typeof window['ga'] === 'function') {
return window['ga']('send', {
hitType: 'event',
eventCategory: data.category,
eventAction: data.action,
eventLabel: data.label,
nonInteraction: !data.interaction,
});
}
throw 'No available analytics backend found. Has Google Analytics been loaded yet?';
};
/**
* Parse an event string and returns a `EventData` object.
* @private
*/
......@@ -267,11 +290,7 @@ var Foresight = /** @class */ (function () {
if (element.getAttribute('data-track:non-interaction') !== null) {
data.interaction = false;
}
gtag('event', data.action, {
'event_label': data.label,
'event_category': data.category,
'non_interaction': !data.interaction,
});
this.send(data);
};
/**
* Handles a view event on an element that is being tracked by Foresight.
......@@ -284,11 +303,7 @@ var Foresight = /** @class */ (function () {
if (element.getAttribute('data-track-view:interaction') !== null) {
data.interaction = true;
}
gtag('event', data.action, {
'event_label': data.label,
'event_category': data.category,
'non_interaction': !data.interaction,
});
this.send(data);
};
/**
* Default Options
......@@ -296,9 +311,10 @@ var Foresight = /** @class */ (function () {
*/
Foresight.defaultOptions = {
defer: false,
observerOptions: {},
clicksAreInteractions: true,
viewsAreInteractions: false,
observerOptions: {},
sendEventFn: null,
};
return Foresight;
}());
......
......@@ -5,4 +5,4 @@
* @author James Ooi <james.ooi@forefront.com.my>
* @license MIT
* @copyright 2018 (c) FOREFRONT International Sdn Bhd
*/var r=this&&this.__assign||function(){return(r=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t}).apply(this,arguments)};n(1);var i=n(2),o=function(){function t(e){var n=this;this._untrackFns=new Map,this._observer=null,this.options=r({},t.defaultOptions,e),this._observer=new IntersectionObserver(function(t,e){t.forEach(function(t){t.isIntersecting&&(n._onTrackedView(t.target,e),e.unobserve(t.target))})},this.options.observerOptions),this.options.defer||this.start()}return t.prototype.start=function(t){var e=this;if(void 0===t&&(t=document.body),void 0===gtag)throw"The 'gtag' function is undefined. Has Google Analytics been loaded yet?";i.toArray(t.querySelectorAll("[data-track], [data-track-view]")).map(function(t){return e.track(t)})},t.prototype.track=function(t){this._untrackFns.has(t)||this._untrackFns.set(t,{click:null,view:null});var e=this._untrackFns.get(t);null!==t.getAttribute("data-track")&&null==e.click&&(e.click=this._trackClicks(t)),null!==t.getAttribute("data-track-view")&&null==e.view&&(e.view=this._trackViews(t)),this._untrackFns.set(t,e)},t.prototype.untrack=function(t){var e=this._untrackFns.get(t);void 0!==e&&(null!==e.click&&e.click(),null!==e.view&&e.view(),this._untrackFns.delete(t))},t.prototype._parseEventString=function(t){var e=t.split(";"),n=e[0],r=e[1],i=e[2];return 1===e.length&&(r=n,n=void 0),{category:n,action:r,label:i,interaction:!0}},t.prototype._trackClicks=function(t){var e=this,n=function(n){e._onTrackedClick(t,n)};return t.addEventListener("click",n),t.addEventListener("auxclick",n),function(){t.removeEventListener("click",n),t.removeEventListener("auxclick",n)}},t.prototype._trackViews=function(t){var e=this;return this._observer.observe(t),function(){e._observer.unobserve(t)}},t.prototype._onTrackedClick=function(t,e){var n=t.getAttribute("data-track"),r=this._parseEventString(n);r.interaction=this.options.clicksAreInteractions,null!==t.getAttribute("data-track:non-interaction")&&(r.interaction=!1),gtag("event",r.action,{event_label:r.label,event_category:r.category,non_interaction:!r.interaction})},t.prototype._onTrackedView=function(t,e){var n=t.getAttribute("data-track-view"),r=this._parseEventString(n);r.interaction=this.options.viewsAreInteractions,null!==t.getAttribute("data-track-view:interaction")&&(r.interaction=!0),gtag("event",r.action,{event_label:r.label,event_category:r.category,non_interaction:!r.interaction})},t.defaultOptions={defer:!1,clicksAreInteractions:!0,viewsAreInteractions:!1,observerOptions:{}},t}();t.exports=o},function(t,e){!function(t,e){"use strict";if("IntersectionObserver"in t&&"IntersectionObserverEntry"in t&&"intersectionRatio"in t.IntersectionObserverEntry.prototype)"isIntersecting"in t.IntersectionObserverEntry.prototype||Object.defineProperty(t.IntersectionObserverEntry.prototype,"isIntersecting",{get:function(){return this.intersectionRatio>0}});else{var n=[];i.prototype.THROTTLE_TIMEOUT=100,i.prototype.POLL_INTERVAL=null,i.prototype.USE_MUTATION_OBSERVER=!0,i.prototype.observe=function(t){if(!this._observationTargets.some(function(e){return e.element==t})){if(!t||1!=t.nodeType)throw new Error("target must be an Element");this._registerInstance(),this._observationTargets.push({element:t,entry:null}),this._monitorIntersections(),this._checkForIntersections()}},i.prototype.unobserve=function(t){this._observationTargets=this._observationTargets.filter(function(e){return e.element!=t}),this._observationTargets.length||(this._unmonitorIntersections(),this._unregisterInstance())},i.prototype.disconnect=function(){this._observationTargets=[],this._unmonitorIntersections(),this._unregisterInstance()},i.prototype.takeRecords=function(){var t=this._queuedEntries.slice();return this._queuedEntries=[],t},i.prototype._initThresholds=function(t){var e=t||[0];return Array.isArray(e)||(e=[e]),e.sort().filter(function(t,e,n){if("number"!=typeof t||isNaN(t)||t<0||t>1)throw new Error("threshold must be a number between 0 and 1 inclusively");return t!==n[e-1]})},i.prototype._parseRootMargin=function(t){var e=(t||"0px").split(/\s+/).map(function(t){var e=/^(-?\d*\.?\d+)(px|%)$/.exec(t);if(!e)throw new Error("rootMargin must be specified in pixels or percent");return{value:parseFloat(e[1]),unit:e[2]}});return e[1]=e[1]||e[0],e[2]=e[2]||e[0],e[3]=e[3]||e[1],e},i.prototype._monitorIntersections=function(){this._monitoringIntersections||(this._monitoringIntersections=!0,this.POLL_INTERVAL?this._monitoringInterval=setInterval(this._checkForIntersections,this.POLL_INTERVAL):(o(t,"resize",this._checkForIntersections,!0),o(e,"scroll",this._checkForIntersections,!0),this.USE_MUTATION_OBSERVER&&"MutationObserver"in t&&(this._domObserver=new MutationObserver(this._checkForIntersections),this._domObserver.observe(e,{attributes:!0,childList:!0,characterData:!0,subtree:!0}))))},i.prototype._unmonitorIntersections=function(){this._monitoringIntersections&&(this._monitoringIntersections=!1,clearInterval(this._monitoringInterval),this._monitoringInterval=null,s(t,"resize",this._checkForIntersections,!0),s(e,"scroll",this._checkForIntersections,!0),this._domObserver&&(this._domObserver.disconnect(),this._domObserver=null))},i.prototype._checkForIntersections=function(){var e=this._rootIsInDom(),n=e?this._getRootRect():{top:0,bottom:0,left:0,right:0,width:0,height:0};this._observationTargets.forEach(function(i){var o=i.element,s=a(o),c=this._rootContainsTarget(o),u=i.entry,h=e&&c&&this._computeTargetAndRootIntersection(o,n),l=i.entry=new r({time:t.performance&&performance.now&&performance.now(),target:o,boundingClientRect:s,rootBounds:n,intersectionRect:h});u?e&&c?this._hasCrossedThreshold(u,l)&&this._queuedEntries.push(l):u&&u.isIntersecting&&this._queuedEntries.push(l):this._queuedEntries.push(l)},this),this._queuedEntries.length&&this._callback(this.takeRecords(),this)},i.prototype._computeTargetAndRootIntersection=function(n,r){if("none"!=t.getComputedStyle(n).display){for(var i=a(n),o=h(n),s=!1;!s;){var u=null,l=1==o.nodeType?t.getComputedStyle(o):{};if("none"==l.display)return;if(o==this.root||o==e?(s=!0,u=r):o!=e.body&&o!=e.documentElement&&"visible"!=l.overflow&&(u=a(o)),u&&!(i=c(u,i)))break;o=h(o)}return i}},i.prototype._getRootRect=function(){var t;if(this.root)t=a(this.root);else{var n=e.documentElement,r=e.body;t={top:0,left:0,right:n.clientWidth||r.clientWidth,width:n.clientWidth||r.clientWidth,bottom:n.clientHeight||r.clientHeight,height:n.clientHeight||r.clientHeight}}return this._expandRectByRootMargin(t)},i.prototype._expandRectByRootMargin=function(t){var e=this._rootMarginValues.map(function(e,n){return"px"==e.unit?e.value:e.value*(n%2?t.width:t.height)/100}),n={top:t.top-e[0],right:t.right+e[1],bottom:t.bottom+e[2],left:t.left-e[3]};return n.width=n.right-n.left,n.height=n.bottom-n.top,n},i.prototype._hasCrossedThreshold=function(t,e){var n=t&&t.isIntersecting?t.intersectionRatio||0:-1,r=e.isIntersecting?e.intersectionRatio||0:-1;if(n!==r)for(var i=0;i<this.thresholds.length;i++){var o=this.thresholds[i];if(o==n||o==r||o<n!=o<r)return!0}},i.prototype._rootIsInDom=function(){return!this.root||u(e,this.root)},i.prototype._rootContainsTarget=function(t){return u(this.root||e,t)},i.prototype._registerInstance=function(){n.indexOf(this)<0&&n.push(this)},i.prototype._unregisterInstance=function(){var t=n.indexOf(this);-1!=t&&n.splice(t,1)},t.IntersectionObserver=i,t.IntersectionObserverEntry=r}function r(t){this.time=t.time,this.target=t.target,this.rootBounds=t.rootBounds,this.boundingClientRect=t.boundingClientRect,this.intersectionRect=t.intersectionRect||{top:0,bottom:0,left:0,right:0,width:0,height:0},this.isIntersecting=!!t.intersectionRect;var e=this.boundingClientRect,n=e.width*e.height,r=this.intersectionRect,i=r.width*r.height;this.intersectionRatio=n?i/n:this.isIntersecting?1:0}function i(t,e){var n=e||{};if("function"!=typeof t)throw new Error("callback must be a function");if(n.root&&1!=n.root.nodeType)throw new Error("root must be an Element");this._checkForIntersections=function(t,e){var n=null;return function(){n||(n=setTimeout(function(){t(),n=null},e))}}(this._checkForIntersections.bind(this),this.THROTTLE_TIMEOUT),this._callback=t,this._observationTargets=[],this._queuedEntries=[],this._rootMarginValues=this._parseRootMargin(n.rootMargin),this.thresholds=this._initThresholds(n.threshold),this.root=n.root||null,this.rootMargin=this._rootMarginValues.map(function(t){return t.value+t.unit}).join(" ")}function o(t,e,n,r){"function"==typeof t.addEventListener?t.addEventListener(e,n,r||!1):"function"==typeof t.attachEvent&&t.attachEvent("on"+e,n)}function s(t,e,n,r){"function"==typeof t.removeEventListener?t.removeEventListener(e,n,r||!1):"function"==typeof t.detatchEvent&&t.detatchEvent("on"+e,n)}function c(t,e){var n=Math.max(t.top,e.top),r=Math.min(t.bottom,e.bottom),i=Math.max(t.left,e.left),o=Math.min(t.right,e.right),s=o-i,c=r-n;return s>=0&&c>=0&&{top:n,bottom:r,left:i,right:o,width:s,height:c}}function a(t){var e;try{e=t.getBoundingClientRect()}catch(t){}return e?(e.width&&e.height||(e={top:e.top,right:e.right,bottom:e.bottom,left:e.left,width:e.right-e.left,height:e.bottom-e.top}),e):{top:0,bottom:0,left:0,right:0,width:0,height:0}}function u(t,e){for(var n=e;n;){if(n==t)return!0;n=h(n)}return!1}function h(t){var e=t.parentNode;return e&&11==e.nodeType&&e.host?e.host:e}}(window,document)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3);e.toArray=r.default},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t){return[].slice.call(t)}}])});
\ No newline at end of file
*/var r=this&&this.__assign||function(){return(r=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t}).apply(this,arguments)};n(1);var i=n(2),o=function(){function t(e){void 0===e&&(e={});var n=this;this._untrackFns=new Map,this._observer=null,this.options=r({},t.defaultOptions,e),this._observer=new IntersectionObserver(function(t,e){t.forEach(function(t){t.isIntersecting&&(n._onTrackedView(t.target,e),e.unobserve(t.target))})},this.options.observerOptions),this.options.defer||this.start()}return t.prototype.start=function(t){var e=this;void 0===t&&(t=document.body),i.toArray(t.querySelectorAll("[data-track], [data-track-view]")).map(function(t){return e.track(t)})},t.prototype.track=function(t){this._untrackFns.has(t)||this._untrackFns.set(t,{click:null,view:null});var e=this._untrackFns.get(t);null!==t.getAttribute("data-track")&&null==e.click&&(e.click=this._trackClicks(t)),null!==t.getAttribute("data-track-view")&&null==e.view&&(e.view=this._trackViews(t)),this._untrackFns.set(t,e)},t.prototype.untrack=function(t){var e=this._untrackFns.get(t);void 0!==e&&(null!==e.click&&e.click(),null!==e.view&&e.view(),this._untrackFns.delete(t))},t.prototype.send=function(t){if(null!==this.options.sendEventFn)return this.options.sendEventFn(t);if("function"==typeof window.gtag)return window.gtag("event",t.action,{event_label:t.label,event_category:t.category,non_interaction:!t.interaction});if("function"==typeof window.ga)return window.ga("send",{hitType:"event",eventCategory:t.category,eventAction:t.action,eventLabel:t.label,nonInteraction:!t.interaction});throw"No available analytics backend found. Has Google Analytics been loaded yet?"},t.prototype._parseEventString=function(t){var e=t.split(";"),n=e[0],r=e[1],i=e[2];return 1===e.length&&(r=n,n=void 0),{category:n,action:r,label:i,interaction:!0}},t.prototype._trackClicks=function(t){var e=this,n=function(n){e._onTrackedClick(t,n)};return t.addEventListener("click",n),t.addEventListener("auxclick",n),function(){t.removeEventListener("click",n),t.removeEventListener("auxclick",n)}},t.prototype._trackViews=function(t){var e=this;return this._observer.observe(t),function(){e._observer.unobserve(t)}},t.prototype._onTrackedClick=function(t,e){var n=t.getAttribute("data-track"),r=this._parseEventString(n);r.interaction=this.options.clicksAreInteractions,null!==t.getAttribute("data-track:non-interaction")&&(r.interaction=!1),this.send(r)},t.prototype._onTrackedView=function(t,e){var n=t.getAttribute("data-track-view"),r=this._parseEventString(n);r.interaction=this.options.viewsAreInteractions,null!==t.getAttribute("data-track-view:interaction")&&(r.interaction=!0),this.send(r)},t.defaultOptions={defer:!1,observerOptions:{},clicksAreInteractions:!0,viewsAreInteractions:!1,sendEventFn:null},t}();t.exports=o},function(t,e){!function(t,e){"use strict";if("IntersectionObserver"in t&&"IntersectionObserverEntry"in t&&"intersectionRatio"in t.IntersectionObserverEntry.prototype)"isIntersecting"in t.IntersectionObserverEntry.prototype||Object.defineProperty(t.IntersectionObserverEntry.prototype,"isIntersecting",{get:function(){return this.intersectionRatio>0}});else{var n=[];i.prototype.THROTTLE_TIMEOUT=100,i.prototype.POLL_INTERVAL=null,i.prototype.USE_MUTATION_OBSERVER=!0,i.prototype.observe=function(t){if(!this._observationTargets.some(function(e){return e.element==t})){if(!t||1!=t.nodeType)throw new Error("target must be an Element");this._registerInstance(),this._observationTargets.push({element:t,entry:null}),this._monitorIntersections(),this._checkForIntersections()}},i.prototype.unobserve=function(t){this._observationTargets=this._observationTargets.filter(function(e){return e.element!=t}),this._observationTargets.length||(this._unmonitorIntersections(),this._unregisterInstance())},i.prototype.disconnect=function(){this._observationTargets=[],this._unmonitorIntersections(),this._unregisterInstance()},i.prototype.takeRecords=function(){var t=this._queuedEntries.slice();return this._queuedEntries=[],t},i.prototype._initThresholds=function(t){var e=t||[0];return Array.isArray(e)||(e=[e]),e.sort().filter(function(t,e,n){if("number"!=typeof t||isNaN(t)||t<0||t>1)throw new Error("threshold must be a number between 0 and 1 inclusively");return t!==n[e-1]})},i.prototype._parseRootMargin=function(t){var e=(t||"0px").split(/\s+/).map(function(t){var e=/^(-?\d*\.?\d+)(px|%)$/.exec(t);if(!e)throw new Error("rootMargin must be specified in pixels or percent");return{value:parseFloat(e[1]),unit:e[2]}});return e[1]=e[1]||e[0],e[2]=e[2]||e[0],e[3]=e[3]||e[1],e},i.prototype._monitorIntersections=function(){this._monitoringIntersections||(this._monitoringIntersections=!0,this.POLL_INTERVAL?this._monitoringInterval=setInterval(this._checkForIntersections,this.POLL_INTERVAL):(o(t,"resize",this._checkForIntersections,!0),o(e,"scroll",this._checkForIntersections,!0),this.USE_MUTATION_OBSERVER&&"MutationObserver"in t&&(this._domObserver=new MutationObserver(this._checkForIntersections),this._domObserver.observe(e,{attributes:!0,childList:!0,characterData:!0,subtree:!0}))))},i.prototype._unmonitorIntersections=function(){this._monitoringIntersections&&(this._monitoringIntersections=!1,clearInterval(this._monitoringInterval),this._monitoringInterval=null,s(t,"resize",this._checkForIntersections,!0),s(e,"scroll",this._checkForIntersections,!0),this._domObserver&&(this._domObserver.disconnect(),this._domObserver=null))},i.prototype._checkForIntersections=function(){var e=this._rootIsInDom(),n=e?this._getRootRect():{top:0,bottom:0,left:0,right:0,width:0,height:0};this._observationTargets.forEach(function(i){var o=i.element,s=a(o),c=this._rootContainsTarget(o),u=i.entry,h=e&&c&&this._computeTargetAndRootIntersection(o,n),l=i.entry=new r({time:t.performance&&performance.now&&performance.now(),target:o,boundingClientRect:s,rootBounds:n,intersectionRect:h});u?e&&c?this._hasCrossedThreshold(u,l)&&this._queuedEntries.push(l):u&&u.isIntersecting&&this._queuedEntries.push(l):this._queuedEntries.push(l)},this),this._queuedEntries.length&&this._callback(this.takeRecords(),this)},i.prototype._computeTargetAndRootIntersection=function(n,r){if("none"!=t.getComputedStyle(n).display){for(var i=a(n),o=h(n),s=!1;!s;){var u=null,l=1==o.nodeType?t.getComputedStyle(o):{};if("none"==l.display)return;if(o==this.root||o==e?(s=!0,u=r):o!=e.body&&o!=e.documentElement&&"visible"!=l.overflow&&(u=a(o)),u&&!(i=c(u,i)))break;o=h(o)}return i}},i.prototype._getRootRect=function(){var t;if(this.root)t=a(this.root);else{var n=e.documentElement,r=e.body;t={top:0,left:0,right:n.clientWidth||r.clientWidth,width:n.clientWidth||r.clientWidth,bottom:n.clientHeight||r.clientHeight,height:n.clientHeight||r.clientHeight}}return this._expandRectByRootMargin(t)},i.prototype._expandRectByRootMargin=function(t){var e=this._rootMarginValues.map(function(e,n){return"px"==e.unit?e.value:e.value*(n%2?t.width:t.height)/100}),n={top:t.top-e[0],right:t.right+e[1],bottom:t.bottom+e[2],left:t.left-e[3]};return n.width=n.right-n.left,n.height=n.bottom-n.top,n},i.prototype._hasCrossedThreshold=function(t,e){var n=t&&t.isIntersecting?t.intersectionRatio||0:-1,r=e.isIntersecting?e.intersectionRatio||0:-1;if(n!==r)for(var i=0;i<this.thresholds.length;i++){var o=this.thresholds[i];if(o==n||o==r||o<n!=o<r)return!0}},i.prototype._rootIsInDom=function(){return!this.root||u(e,this.root)},i.prototype._rootContainsTarget=function(t){return u(this.root||e,t)},i.prototype._registerInstance=function(){n.indexOf(this)<0&&n.push(this)},i.prototype._unregisterInstance=function(){var t=n.indexOf(this);-1!=t&&n.splice(t,1)},t.IntersectionObserver=i,t.IntersectionObserverEntry=r}function r(t){this.time=t.time,this.target=t.target,this.rootBounds=t.rootBounds,this.boundingClientRect=t.boundingClientRect,this.intersectionRect=t.intersectionRect||{top:0,bottom:0,left:0,right:0,width:0,height:0},this.isIntersecting=!!t.intersectionRect;var e=this.boundingClientRect,n=e.width*e.height,r=this.intersectionRect,i=r.width*r.height;this.intersectionRatio=n?i/n:this.isIntersecting?1:0}function i(t,e){var n=e||{};if("function"!=typeof t)throw new Error("callback must be a function");if(n.root&&1!=n.root.nodeType)throw new Error("root must be an Element");this._checkForIntersections=function(t,e){var n=null;return function(){n||(n=setTimeout(function(){t(),n=null},e))}}(this._checkForIntersections.bind(this),this.THROTTLE_TIMEOUT),this._callback=t,this._observationTargets=[],this._queuedEntries=[],this._rootMarginValues=this._parseRootMargin(n.rootMargin),this.thresholds=this._initThresholds(n.threshold),this.root=n.root||null,this.rootMargin=this._rootMarginValues.map(function(t){return t.value+t.unit}).join(" ")}function o(t,e,n,r){"function"==typeof t.addEventListener?t.addEventListener(e,n,r||!1):"function"==typeof t.attachEvent&&t.attachEvent("on"+e,n)}function s(t,e,n,r){"function"==typeof t.removeEventListener?t.removeEventListener(e,n,r||!1):"function"==typeof t.detatchEvent&&t.detatchEvent("on"+e,n)}function c(t,e){var n=Math.max(t.top,e.top),r=Math.min(t.bottom,e.bottom),i=Math.max(t.left,e.left),o=Math.min(t.right,e.right),s=o-i,c=r-n;return s>=0&&c>=0&&{top:n,bottom:r,left:i,right:o,width:s,height:c}}function a(t){var e;try{e=t.getBoundingClientRect()}catch(t){}return e?(e.width&&e.height||(e={top:e.top,right:e.right,bottom:e.bottom,left:e.left,width:e.right-e.left,height:e.bottom-e.top}),e):{top:0,bottom:0,left:0,right:0,width:0,height:0}}function u(t,e){for(var n=e;n;){if(n==t)return!0;n=h(n)}return!1}function h(t){var e=t.parentNode;return e&&11==e.nodeType&&e.host?e.host:e}}(window,document)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3);e.toArray=r.default},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t){return[].slice.call(t)}}])});
\ No newline at end of file
......@@ -27,6 +27,9 @@ interface ForesightConfig {
/** Treat views as an interactive event. Defaults to `false`. */
viewsAreInteractions?: boolean
/** Override the default send event function. */
sendEventFn?: (data: EventData) => any
}
/**
......@@ -41,8 +44,7 @@ interface EventData {
/**
* Foresight is an analytics library that allows for declarative event tracking
* in your websites.
* Foresight is an analytics library that allows for declarative event tracking.
* @class
*/
class Foresight {
......@@ -56,6 +58,7 @@ class Foresight {
observerOptions: {},
clicksAreInteractions: true,
viewsAreInteractions: false,
sendEventFn: null,
}
/**
......@@ -104,10 +107,6 @@ class Foresight {
* @param {Element} root The container to scan for elements. Defaults to `body`.
*/
start(root: Element = document.body) {
if (gtag === undefined) {
throw `The 'gtag' function is undefined. Has Google Analytics been loaded yet?`;
}
Utils
.toArray<Element>(root.querySelectorAll('[data-track], [data-track-view]'))
.map(element => this.track(element));
......@@ -162,6 +161,35 @@ class Foresight {
}
/**
* Manually send an analytics event data.
*/
send(data: EventData) {
if (this.options.sendEventFn !== null) {
return this.options.sendEventFn(data);
}
if (typeof window['gtag'] === 'function') {
return window['gtag']('event', data.action, {
'event_label': data.label,
'event_category': data.category,
'non_interaction': !data.interaction,
});
}
if (typeof window['ga'] === 'function') {
return window['ga']('send', {
hitType: 'event',
eventCategory: data.category,
eventAction: data.action,
eventLabel: data.label,
nonInteraction: !data.interaction,
})
}
throw 'No available analytics backend found. Has Google Analytics been loaded yet?';
}
/**
* Parse an event string and returns a `EventData` object.
* @private
*/
......@@ -230,11 +258,7 @@ class Foresight {
data.interaction = false;
}
gtag('event', data.action, {
'event_label': data.label,
'event_category': data.category,
'non_interaction': !data.interaction,
});
this.send(data);
}
/**
......@@ -250,11 +274,7 @@ class Foresight {
data.interaction = true;
}
gtag('event', data.action, {
'event_label': data.label,
'event_category': data.category,
'non_interaction': !data.interaction,
});
this.send(data);
}
}
......
......@@ -14,14 +14,24 @@ interface ForesightConfig {
defer?: boolean;
/** Configure the intersection observer. */
observerOptions?: IntersectionObserverInit;
/** Treat clicks as an interactive event. Defaults to true. */
/** Treat clicks as an interactive event. Defaults to `true`. */
clicksAreInteractions?: boolean;
/** Treat views as an interactive event. Defaults to false. */
/** Treat views as an interactive event. Defaults to `false`. */
viewsAreInteractions?: boolean;
/** Override the default send event function. */
sendEventFn?: (data: EventData) => any;
}
/**
* Foresight is an analytics library that allows for declarative event tracking
* in your websites.
* Represents a particular event's data.
*/
interface EventData {
category: string;
action: string;
label: string;
interaction: boolean;
}
/**
* Foresight is an analytics library that allows for declarative event tracking.
* @class
*/
declare class Foresight {
......@@ -49,20 +59,25 @@ declare class Foresight {
/**
* @constructor
*/
constructor(config: ForesightConfig);
constructor(config?: ForesightConfig);
/**
* Start event tracking for all DOM elements with event tracking attributes.
* Start tracking all elements with tracking attributes for events.
* @param {Element} root The container to scan for elements. Defaults to `body`.
*/
start(root?: Element): void;
/**
* Enables event tracking for a DOM element with event tracking attribute.
* Start tracking an element for events.
*/
track(element: Element): void;
/**
* Disable event tracking for a DOM element.
* Stop tracking an element for events.
*/
untrack(element: Element): void;
/**
* Manually send an analytics event data.
*/
send(data: EventData): any;
/**
* Parse an event string and returns a `EventData` object.
* @private
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment