Skip to content

Commit

Permalink
Make outbound link/form logic configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
philipwalton committed Feb 17, 2016
1 parent 958ebeb commit d7381da
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 12 deletions.
2 changes: 1 addition & 1 deletion autotrack.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion autotrack.js.map

Large diffs are not rendered by default.

22 changes: 18 additions & 4 deletions lib/plugins/outbound-form-tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ function OutboundFormTracker(tracker, opts) {
// Feature detects to prevent errors in unsupporting browsers.
if (!window.addEventListener) return;

this.opts = defaults(opts);
this.opts = defaults(opts, {
shouldTrackOutboundForm: this.shouldTrackOutboundForm
});

this.tracker = tracker;

delegate(document, 'form', 'submit', this.handleFormSubmits.bind(this));
Expand All @@ -57,9 +60,7 @@ OutboundFormTracker.prototype.handleFormSubmits = function(event) {
var action = form.getAttribute('action');
var fieldsObj = {transport: 'beacon'};

// Checks if the action is outbound.
if (action.indexOf('http') === 0 &&
action.indexOf(location.hostname) < 0) {
if (this.opts.shouldTrackOutboundForm(form)) {

if (!navigator.sendBeacon) {
// Stops the submit and waits until the hit is complete (with timeout)
Expand All @@ -75,4 +76,17 @@ OutboundFormTracker.prototype.handleFormSubmits = function(event) {
};


/**
* Determines whether or not the tracker should send a hit when a form is
* submitted. By default, forms with an action attribute that starts with
* "http" and doesn't contain the current hostname are tracked.
* @param {Element} form The form that was submitted.
* @return {boolean} Whether or not the form should be tracked.
*/
OutboundFormTracker.prototype.shouldTrackOutboundForm = function(form) {
var action = form.getAttribute('action');
return action.indexOf('http') === 0 && action.indexOf(location.hostname) < 0;
};


provide('outboundFormTracker', OutboundFormTracker);
24 changes: 18 additions & 6 deletions lib/plugins/outbound-link-tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ function OutboundLinkTracker(tracker, opts) {
// Feature detects to prevent errors in unsupporting browsers.
if (!window.addEventListener) return;

this.opts = defaults(opts);
this.opts = defaults(opts, {
shouldTrackOutboundLink: this.shouldTrackOutboundLink
});

this.tracker = tracker;

delegate(document, 'a', 'click', this.handleLinkClicks.bind(this));
Expand All @@ -50,12 +53,9 @@ function OutboundLinkTracker(tracker, opts) {
* @param {Event} event The DOM click event.
*/
OutboundLinkTracker.prototype.handleLinkClicks = function(event) {

// TODO(philipwalton): ignore outbound links with data attributes.

var link = event.delegateTarget;
if (link.hostname != location.hostname) {
// Open outbound links in a new tab if the browser doesn't support
if (this.opts.shouldTrackOutboundLink(link)) {
// Opens outbound links in a new tab if the browser doesn't support
// the beacon transport method.
if (!navigator.sendBeacon) {
link.target = '_blank';
Expand All @@ -67,4 +67,16 @@ OutboundLinkTracker.prototype.handleLinkClicks = function(event) {
};


/**
* Determines whether or not the tracker should send a hit when a link is
* clicked. By default links with a hostname property not equal to the current
* hostname are tracked.
* @param {Element} link The link that was clicked on.
* @return {boolean} Whether or not the link should be tracked.
*/
OutboundLinkTracker.prototype.shouldTrackOutboundLink = function(link) {
return link.hostname != location.hostname;
};


provide('outboundLinkTracker', OutboundLinkTracker);
52 changes: 52 additions & 0 deletions test/outbound-form-tracker-conditional.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!doctype html>
<html>
<body>
<script>

window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;

ga('create', 'UA-XXXXX-Y', 'auto');

// Note(philipwalton):
// Selenium on Windows 10 Edge doesn't handle arrays well, so we fake it.
var hitData = {count: 0};
ga('set', 'sendHitTask', function(model) {
hitData[hitData.count] = {
eventCategory: model.get('eventCategory'),
eventAction: model.get('eventAction'),
eventLabel: model.get('eventLabel'),
devId: model.get('&did')
};
hitData.count++;
});

ga('require', 'outboundFormTracker', {
shouldTrackOutboundForm: function(form) {
var action = form.getAttribute('action');
return action.indexOf('google-analytics.com') < 0;
}
});

</script>

<form action="http://google-analytics.com/collect">
<input id="submit-1" type="submit">
</form>

<form action="/test/blank.html">
<input id="submit-2" type="submit">
</form>

<script>
document.addEventListener('submit', function(event) {
if (window.__stopFormSubmitEvents__) {
event.preventDefault();
}
});
</script>

<script async src='//www.google-analytics.com/analytics.js'></script>
<script aysnc src="/autotrack.js"></script>

</body>
</html>
15 changes: 15 additions & 0 deletions test/outbound-form-tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@ describe('outboundFormTracker', function() {
});


it('should allow customizing what is considered an outbound form',
function *() {

var testData = (yield browser
.url('/test/outbound-form-tracker-conditional.html')
.execute(stopFormSubmitEvents)
.execute(stubBeacon)
.click('#submit-1')
.execute(getHitData))
.value;

assert(!testData.count);
});


it('should navigate to the proper location on submit', function *() {

yield browser
Expand Down
46 changes: 46 additions & 0 deletions test/outbound-link-tracker-conditional.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!doctype html>
<html>
<body>
<script>

window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;

ga('create', 'UA-XXXXX-Y', 'auto');

// Note(philipwalton):
// Selenium on Windows 10 Edge doesn't handle arrays well, so we fake it.
var hitData = {count: 0};
ga('set', 'sendHitTask', function(model) {
hitData[hitData.count] = {
eventCategory: model.get('eventCategory'),
eventAction: model.get('eventAction'),
eventLabel: model.get('eventLabel'),
devId: model.get('&did')
};
hitData.count++;
});

ga('require', 'outboundLinkTracker', {
shouldTrackOutboundLink: function(link) {
return link.hostname != 'google-analytics.com';
}
});

</script>

<a id="outbound-link" href="http://google-analytics.com/collect">Outbound</a>
<a id="local-link" href="/test/blank.html">Local</a>

<script>
document.addEventListener('click', function(event) {
if (window.__stopClickEvents__) {
event.preventDefault();
}
});
</script>

<script async src='//www.google-analytics.com/analytics.js'></script>
<script aysnc src="/autotrack.js"></script>

</body>
</html>
15 changes: 15 additions & 0 deletions test/outbound-link-tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@ describe('outboundLinkTracker', function() {
});


it('should allow customizing what is considered an outbound link',
function*() {

var testData = (yield browser
.url('/test/outbound-link-tracker-conditional.html')
.execute(stopClickEvents)
.execute(stubBeacon)
.click('#outbound-link')
.execute(getHitData))
.value;

assert(!testData.count);
});


it('should navigate to the proper location on submit', function *() {

yield browser
Expand Down

0 comments on commit d7381da

Please sign in to comment.