From d9d023cc727f53311a76e64954db80b03fa83885 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Fri, 6 Jun 2014 09:22:06 +0100
Subject: [PATCH 0001/1261] Added guard to prevent document size field from
being set as "NaNxNaN" (#220)
---
CHANGELOG | 4 ++++
package.json | 2 +-
src/js/lib/detectors.js | 2 +-
src/js/snowplow.js | 2 +-
4 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 65a7034bc..4bbea82db 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+Version 1.0.2 (2014-04-xx)
+--------------------------
+Added guard to prevent document size field from being set as "NaNxNaN" (#220)
+
Version 1.0.1 (2014-04-09)
--------------------------
Fixed lodash.js to work in the presence of AMD modules (#165)
diff --git a/package.json b/package.json
index fabecef4b..6f8e3915c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "snowplow-tracker",
- "version": "1.0.1",
+ "version": "1.0.2",
"devDependencies": {
"grunt": "~0.4.2",
"intern": "~1.4.0",
diff --git a/src/js/lib/detectors.js b/src/js/lib/detectors.js
index 25c0fb2bd..df2c1c0fb 100644
--- a/src/js/lib/detectors.js
+++ b/src/js/lib/detectors.js
@@ -155,7 +155,7 @@
var de = documentAlias.documentElement; // Alias
var w = Math.max(de.clientWidth, de.offsetWidth, de.scrollWidth);
var h = Math.max(de.clientHeight, de.offsetHeight, de.scrollHeight);
- return w + 'x' + h;
+ return isNaN(w) || isNaN(h) ? '' : w + 'x' + h;
}
/*
diff --git a/src/js/snowplow.js b/src/js/snowplow.js
index 3c975fd72..45e5c0ed1 100644
--- a/src/js/snowplow.js
+++ b/src/js/snowplow.js
@@ -88,7 +88,7 @@
windowAlias = window,
/* Tracker identifier with version */
- version = 'js-1.0.0', // Update banner.js too
+ version = 'js-1.0.2', // Update banner.js too
/* Contains three variables that are shared with tracker.js and must be passed by reference */
mutSnowplowState = {
From 22dbcdc341bf0869d73add78dbefddeac2749aed Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Fri, 6 Jun 2014 09:43:27 +0100
Subject: [PATCH 0002/1261] Corrected month
---
CHANGELOG | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 4bbea82db..10576b090 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,4 @@
-Version 1.0.2 (2014-04-xx)
+Version 1.0.2 (2014-06-xx)
--------------------------
Added guard to prevent document size field from being set as "NaNxNaN" (#220)
From 12ab08bcb45400847f957a48c7b7ce8947fe4f54 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Fri, 6 Jun 2014 10:09:59 +0100
Subject: [PATCH 0003/1261] Fixed Grunt publish tasks to build sp.js as well as
upload it to S3 (#224)
---
CHANGELOG | 1 +
Gruntfile.js | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 10576b090..f1de337a4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
Version 1.0.2 (2014-06-xx)
--------------------------
Added guard to prevent document size field from being set as "NaNxNaN" (#220)
+Fixed Grunt publish tasks to build sp.js as well as upload it to S3 (#224)
Version 1.0.1 (2014-04-09)
--------------------------
diff --git a/Gruntfile.js b/Gruntfile.js
index 8ac37acc8..e45959a6f 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -198,8 +198,8 @@ module.exports = function(grunt) {
});
grunt.registerTask('default', 'Build lodash, Browserify, add banner, and minify', ['lodash', 'browserify', 'concat', 'min']);
- grunt.registerTask('publish', 'Upload to S3 and invalidate Cloudfront (full semantic version only)', ['upload_setup', 'concat', 'min', 's3:not_pinned', 'invalidate_cloudfront:not_pinned']);
- grunt.registerTask('publish-pinned', 'Upload to S3 and invalidate Cloudfront (full semantic version and semantic major version)', ['upload_setup', 'concat', 'min', 's3', 'invalidate_cloudfront']);
+ grunt.registerTask('publish', 'Upload to S3 and invalidate Cloudfront (full semantic version only)', ['upload_setup', 'lodash', 'browserify', 'concat', 'min', 's3:not_pinned', 'invalidate_cloudfront:not_pinned']);
+ grunt.registerTask('publish-pinned', 'Upload to S3 and invalidate Cloudfront (full semantic version and semantic major version)', ['upload_setup', 'lodash', 'browserify', 'concat', 'min', 's3', 'invalidate_cloudfront']);
grunt.registerTask('travis', 'Intern tests for Travis CI', ['lodash','intern']);
}
From 7e86fb0ff49ae54983426522a6d219df49870b46 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 11 Jun 2014 14:06:58 +0100
Subject: [PATCH 0004/1261] Added cache control to Grunt upload for full
semantic version (#225)
---
CHANGELOG | 1 +
Gruntfile.js | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index f1de337a4..f20fa842e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,7 @@ Version 1.0.2 (2014-06-xx)
--------------------------
Added guard to prevent document size field from being set as "NaNxNaN" (#220)
Fixed Grunt publish tasks to build sp.js as well as upload it to S3 (#224)
+Added cache control to Grunt upload for full semantic version (#225)
Version 1.0.1 (2014-04-09)
--------------------------
diff --git a/Gruntfile.js b/Gruntfile.js
index e45959a6f..4c339d062 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -155,6 +155,11 @@ module.exports = function(grunt) {
gzip: true
},
not_pinned: {
+ options: {
+ headers: {
+ 'Cache-Control': 'max-age=315360000'
+ }
+ },
upload: [
{
src: 'dist/sp.js',
@@ -163,6 +168,11 @@ module.exports = function(grunt) {
]
},
pinned: {
+ options: {
+ headers: {
+ 'Cache-Control': 'max-age=3600'
+ }
+ },
upload: [
{
src: 'dist/sp.js',
From 88997cd859e375591ce2d8729bc96c8a1053f815 Mon Sep 17 00:00:00 2001
From: Alex Dean
Date: Tue, 24 Jun 2014 18:01:50 +0100
Subject: [PATCH 0005/1261] Finalized date
---
CHANGELOG | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index f20fa842e..f70dbb9d7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,4 @@
-Version 1.0.2 (2014-06-xx)
+Version 1.0.2 (2014-06-24)
--------------------------
Added guard to prevent document size field from being set as "NaNxNaN" (#220)
Fixed Grunt publish tasks to build sp.js as well as upload it to S3 (#224)
From d00befe45c5d41da85172e71074b56af33aa59b5 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Fri, 27 Jun 2014 13:51:54 +0100
Subject: [PATCH 0006/1261] Changed Base64 encoding function to prevent
character encoding errors (#231)
---
CHANGELOG | 4 ++++
package.json | 3 +--
src/js/payload.js | 6 ++----
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index f70dbb9d7..b1ff0ef95 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+Version 1.0.3 (2014-XX-XX)
+--------------------------
+Changed Base64 encoding function to prevent character encoding errors (#231)
+
Version 1.0.2 (2014-06-24)
--------------------------
Added guard to prevent document size field from being set as "NaNxNaN" (#220)
diff --git a/package.json b/package.json
index 6f8e3915c..7f503ee68 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "snowplow-tracker",
- "version": "1.0.2",
+ "version": "1.0.3",
"devDependencies": {
"grunt": "~0.4.2",
"intern": "~1.4.0",
@@ -14,7 +14,6 @@
"grunt-browserify": "~1.3.0",
"jstimezonedetect": "~1.0.5",
"JSON": "~1.0.0",
- "Base64": "~0.2.0",
"sha1": "git://github.com/pvorb/node-sha1.git#v1.0.0",
"grunt-lodash": "~0.3.0"
},
diff --git a/src/js/payload.js b/src/js/payload.js
index 7dc633a6e..b875ec2c0 100644
--- a/src/js/payload.js
+++ b/src/js/payload.js
@@ -37,9 +37,7 @@
var
lodash = require('./lib/lodash'),
json2 = require('JSON'),
- Base64 = require('Base64'),
- base64encode = Base64.btoa,
- base64decode = Base64.atob,
+ base64 = require('./lib/base64'),
object = typeof exports !== 'undefined' ? exports : this; // For eventual node.js environment support
@@ -51,7 +49,7 @@
function base64urlencode(data) {
if (!data) return data;
- var enc = base64encode(data);
+ var enc = base64.base64encode(data);
return enc.replace(/=/g, '')
.replace(/\+/g, '-')
.replace(/\//g, '_');
From b21682dec7b5bc46084192482a59b558b825d171 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Fri, 27 Jun 2014 13:54:24 +0100
Subject: [PATCH 0007/1261] Added new file and bumped version to 1.0.3
---
src/js/lib/base64.js | 82 ++++++++++++++++++++++++++++++++++++++++++++
src/js/snowplow.js | 2 +-
2 files changed, 83 insertions(+), 1 deletion(-)
create mode 100644 src/js/lib/base64.js
diff --git a/src/js/lib/base64.js b/src/js/lib/base64.js
new file mode 100644
index 000000000..715c0e63b
--- /dev/null
+++ b/src/js/lib/base64.js
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io)
+ * and Contributors (http://phpjs.org/authors)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+(function() {
+
+ var object = typeof exports !== 'undefined' ? exports : this; // For eventual node.js environment support
+
+ function base64_encode(data) {
+ // discuss at: http://phpjs.org/functions/base64_encode/
+ // original by: Tyler Akins (http://rumkin.com)
+ // improved by: Bayron Guevara
+ // improved by: Thunder.m
+ // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+ // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+ // improved by: Rafał Kukawski (http://kukawski.pl)
+ // bugfixed by: Pellentesque Malesuada
+ // example 1: base64_encode('Kevin van Zonneveld');
+ // returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='
+ // example 2: base64_encode('a');
+ // returns 2: 'YQ=='
+ // example 3: base64_encode('✓ à la mode');
+ // returns 3: '4pyTIMOgIGxhIG1vZGU='
+
+ var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+ var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
+ ac = 0,
+ enc = '',
+ tmp_arr = [];
+
+ if (!data) {
+ return data;
+ }
+
+ data = unescape(encodeURIComponent(data));
+
+ do {
+ // pack three octets into four hexets
+ o1 = data.charCodeAt(i++);
+ o2 = data.charCodeAt(i++);
+ o3 = data.charCodeAt(i++);
+
+ bits = o1 << 16 | o2 << 8 | o3;
+
+ h1 = bits >> 18 & 0x3f;
+ h2 = bits >> 12 & 0x3f;
+ h3 = bits >> 6 & 0x3f;
+ h4 = bits & 0x3f;
+
+ // use hexets to index into b64, and append result to encoded string
+ tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
+ } while (i < data.length);
+
+ enc = tmp_arr.join('');
+
+ var r = data.length % 3;
+
+ return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3);
+ }
+
+ object.base64encode = base64_encode;
+
+}());
diff --git a/src/js/snowplow.js b/src/js/snowplow.js
index 45e5c0ed1..4c5b13696 100644
--- a/src/js/snowplow.js
+++ b/src/js/snowplow.js
@@ -88,7 +88,7 @@
windowAlias = window,
/* Tracker identifier with version */
- version = 'js-1.0.2', // Update banner.js too
+ version = 'js-1.0.3',
/* Contains three variables that are shared with tracker.js and must be passed by reference */
mutSnowplowState = {
From 62f8c0eb093c661c5de77a297ec174b9c1fa3a27 Mon Sep 17 00:00:00 2001
From: Alex Dean
Date: Sat, 28 Jun 2014 00:40:44 +0100
Subject: [PATCH 0008/1261] Finalized CHANGELOG for release
---
CHANGELOG | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index b1ff0ef95..6537fee96 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,4 @@
-Version 1.0.3 (2014-XX-XX)
+Version 1.0.3 (2014-06-27)
--------------------------
Changed Base64 encoding function to prevent character encoding errors (#231)
From 869f8ec4567dce5577b149b439f5d096390a60f9 Mon Sep 17 00:00:00 2001
From: Alex Dean
Date: Sat, 28 Jun 2014 00:41:15 +0100
Subject: [PATCH 0009/1261] Added in credit
---
CHANGELOG | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 6537fee96..a0dcc374f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,6 @@
Version 1.0.3 (2014-06-27)
--------------------------
-Changed Base64 encoding function to prevent character encoding errors (#231)
+Changed Base64 encoding function to prevent character encoding errors, thanks @shermozle! (#231)
Version 1.0.2 (2014-06-24)
--------------------------
From 7db7d7b4211e136689668cf05a79d5532c640133 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 26 Feb 2014 09:48:59 +0000
Subject: [PATCH 0010/1261] Added TODOs for 1.0.0
---
CHANGELOG | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index a0dcc374f..69b849526 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,19 @@ Added guard to prevent document size field from being set as "NaNxNaN" (#220)
Fixed Grunt publish tasks to build sp.js as well as upload it to S3 (#224)
Added cache control to Grunt upload for full semantic version (#225)
+Version 1.1.0 (2014-02-XX)
+--------------------------
+Moved fixUpUrl into its own file, called lib/proxies.js (#112) (TODO)
+Fixed duplication of querystring parameter lookup (#111) (TODO)
+Tried running Snowplow JS Tracker from PhoneGap (#107) (TODO)
+Added tests for helpers.js (#96) (TODO)
+Added tests for detectors.js (#95) (TODO)
+Replaced cookie.js with browser-cookie-lite (#88) (TODO)
+Added ad conversion tracking (#60) (TODO)
+Added ad click tracking (#59) (TODO)
+Added initial localStorage support for intermittent offline beacons (#24) (TODO)
+Added new trackAdImpression, mapping to unstructured event (#13) (TODO)
+
Version 1.0.1 (2014-04-09)
--------------------------
Fixed lodash.js to work in the presence of AMD modules (#165)
From 8bf2a1e7445fc943024ec39556aa67e009e5a54d Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 26 Feb 2014 09:59:35 +0000
Subject: [PATCH 0011/1261] Moved fixUpUrl into its own file, called
lib/proxies.js (#112)
---
CHANGELOG | 2 +-
src/js/lib/helpers.js | 33 --------------------
src/js/lib/proxies.js | 72 +++++++++++++++++++++++++++++++++++++++++++
src/js/tracker.js | 4 ++-
4 files changed, 76 insertions(+), 35 deletions(-)
create mode 100644 src/js/lib/proxies.js
diff --git a/CHANGELOG b/CHANGELOG
index 69b849526..3ba2ad57a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,7 +10,7 @@ Added cache control to Grunt upload for full semantic version (#225)
Version 1.1.0 (2014-02-XX)
--------------------------
-Moved fixUpUrl into its own file, called lib/proxies.js (#112) (TODO)
+Moved fixUpUrl into its own file, called lib/proxies.js (#112)
Fixed duplication of querystring parameter lookup (#111) (TODO)
Tried running Snowplow JS Tracker from PhoneGap (#107) (TODO)
Added tests for helpers.js (#96) (TODO)
diff --git a/src/js/lib/helpers.js b/src/js/lib/helpers.js
index e5c45c258..2a96db719 100644
--- a/src/js/lib/helpers.js
+++ b/src/js/lib/helpers.js
@@ -71,39 +71,6 @@
return matches ? matches[1] : url;
}
- /*
- * Fix-up URL when page rendered from search engine cache or translated page.
- * TODO: it would be nice to generalise this and/or move into the ETL phase.
- */
- object.fixupUrl = function (hostName, href, referrer) {
- /*
- * Extract parameter from URL
- */
- function getParameter(url, name) {
- // scheme : // [username [: password] @] hostname [: port] [/ [path] [? query] [# fragment]]
- var e = new RegExp('^(?:https?|ftp)(?::/*(?:[^?]+)[?])([^#]+)'),
- matches = e.exec(url),
- f = new RegExp('(?:^|&)' + name + '=([^&]*)'),
- result = matches ? f.exec(matches[1]) : 0;
-
- return result ? decodeURIComponent(result[1]) : '';
- }
-
- if (hostName === 'translate.googleusercontent.com') { // Google
- if (referrer === '') {
- referrer = href;
- }
- href = getParameter(href, 'u');
- hostName = object.getHostName(href);
- } else if (hostName === 'cc.bingj.com' || // Bing
- hostName === 'webcache.googleusercontent.com' || // Google
- hostName.slice(0, 5) === '74.6.') { // Yahoo (via Inktomi 74.6.0.0/16)
- href = document.links[0].href;
- hostName = object.getHostName(href);
- }
- return [hostName, href, referrer];
- }
-
/*
* Fix-up domain
*/
diff --git a/src/js/lib/proxies.js b/src/js/lib/proxies.js
new file mode 100644
index 000000000..f09e5fc0a
--- /dev/null
+++ b/src/js/lib/proxies.js
@@ -0,0 +1,72 @@
+/*
+ * JavaScript tracker for Snowplow: proxies.js
+ *
+ * Significant portions copyright 2010 Anthon Pang. Remainder copyright
+ * 2012-2014 Snowplow Analytics Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Anthon Pang nor Snowplow Analytics Ltd nor the
+ * names of their contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+;(function(){
+
+ var object = typeof exports !== 'undefined' ? exports : this;
+
+ /*
+ * Fix-up URL when page rendered from search engine cache or translated page.
+ * TODO: it would be nice to generalise this and/or move into the ETL phase.
+ */
+ object.fixupUrl = function (hostName, href, referrer) {
+ /*
+ * Extract parameter from URL
+ */
+ function getParameter(url, name) {
+ // scheme : // [username [: password] @] hostname [: port] [/ [path] [? query] [# fragment]]
+ var e = new RegExp('^(?:https?|ftp)(?::/*(?:[^?]+)[?])([^#]+)'),
+ matches = e.exec(url),
+ f = new RegExp('(?:^|&)' + name + '=([^&]*)'),
+ result = matches ? f.exec(matches[1]) : 0;
+
+ return result ? decodeURIComponent(result[1]) : '';
+ }
+
+ if (hostName === 'translate.googleusercontent.com') { // Google
+ if (referrer === '') {
+ referrer = href;
+ }
+ href = getParameter(href, 'u');
+ hostName = object.getHostName(href);
+ } else if (hostName === 'cc.bingj.com' || // Bing
+ hostName === 'webcache.googleusercontent.com' || // Google
+ hostName.slice(0, 5) === '74.6.') { // Yahoo (via Inktomi 74.6.0.0/16)
+ href = document.links[0].href;
+ hostName = object.getHostName(href);
+ }
+ return [hostName, href, referrer];
+ }
+
+}());
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 9ee49c46e..3283a8d01 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -37,12 +37,14 @@
var
lodash = require('./lib/lodash'),
helpers = require('./lib/helpers'),
+ proxies = require('./lib/proxies'),
cookie = require('./lib/cookie'),
detectors = require('./lib/detectors'),
payload = require('./payload'),
json2 = require('JSON'),
sha1 = require('sha1'),
+
object = typeof exports !== 'undefined' ? exports : this; // For eventual node.js environment support
/*
@@ -76,7 +78,7 @@
navigatorAlias = navigator,
// Current URL and Referrer URL
- locationArray = helpers.fixupUrl(documentAlias.domain, windowAlias.location.href, helpers.getReferrer()),
+ locationArray = proxies.fixupUrl(documentAlias.domain, windowAlias.location.href, helpers.getReferrer()),
domainAlias = helpers.fixupDomain(locationArray[0]),
locationHrefAlias = locationArray[1],
configReferrerUrl = locationArray[2],
From 0f143b1e7090dc99100f7df2007392a011584bfb Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 26 Feb 2014 11:06:34 +0000
Subject: [PATCH 0012/1261] proxies.js now has helpers.js as a Browserify
dependency
---
src/js/lib/proxies.js | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/js/lib/proxies.js b/src/js/lib/proxies.js
index f09e5fc0a..7bd17980f 100644
--- a/src/js/lib/proxies.js
+++ b/src/js/lib/proxies.js
@@ -34,7 +34,9 @@
;(function(){
- var object = typeof exports !== 'undefined' ? exports : this;
+ var
+ helpers = require('./helpers'),
+ object = typeof exports !== 'undefined' ? exports : this;
/*
* Fix-up URL when page rendered from search engine cache or translated page.
@@ -50,7 +52,7 @@
matches = e.exec(url),
f = new RegExp('(?:^|&)' + name + '=([^&]*)'),
result = matches ? f.exec(matches[1]) : 0;
-
+console.log('matches:', matches)
return result ? decodeURIComponent(result[1]) : '';
}
@@ -59,12 +61,12 @@
referrer = href;
}
href = getParameter(href, 'u');
- hostName = object.getHostName(href);
+ hostName = helpers.getHostName(href);
} else if (hostName === 'cc.bingj.com' || // Bing
hostName === 'webcache.googleusercontent.com' || // Google
hostName.slice(0, 5) === '74.6.') { // Yahoo (via Inktomi 74.6.0.0/16)
href = document.links[0].href;
- hostName = object.getHostName(href);
+ hostName = helpers.getHostName(href);
}
return [hostName, href, referrer];
}
From 98b3f3a2d088eb1ab4765446c5e6d57f7bea7bd4 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 26 Feb 2014 11:08:51 +0000
Subject: [PATCH 0013/1261] Removed debug code from proxies.js
---
src/js/lib/proxies.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/js/lib/proxies.js b/src/js/lib/proxies.js
index 7bd17980f..24777c468 100644
--- a/src/js/lib/proxies.js
+++ b/src/js/lib/proxies.js
@@ -52,7 +52,7 @@
matches = e.exec(url),
f = new RegExp('(?:^|&)' + name + '=([^&]*)'),
result = matches ? f.exec(matches[1]) : 0;
-console.log('matches:', matches)
+
return result ? decodeURIComponent(result[1]) : '';
}
From c71ebaf4400459131a37e6745dd68166054c0ccc Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 26 Feb 2014 09:48:59 +0000
Subject: [PATCH 0014/1261] Added TODOs for 1.0.0
---
CHANGELOG | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3ba2ad57a..69b849526 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,7 +10,7 @@ Added cache control to Grunt upload for full semantic version (#225)
Version 1.1.0 (2014-02-XX)
--------------------------
-Moved fixUpUrl into its own file, called lib/proxies.js (#112)
+Moved fixUpUrl into its own file, called lib/proxies.js (#112) (TODO)
Fixed duplication of querystring parameter lookup (#111) (TODO)
Tried running Snowplow JS Tracker from PhoneGap (#107) (TODO)
Added tests for helpers.js (#96) (TODO)
From 4b57bda3ed8abbf2523e5a8349c6a85e389ab0f6 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 26 Feb 2014 09:59:35 +0000
Subject: [PATCH 0015/1261] Moved fixUpUrl into its own file, called
lib/proxies.js (#112)
---
CHANGELOG | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 69b849526..3ba2ad57a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,7 +10,7 @@ Added cache control to Grunt upload for full semantic version (#225)
Version 1.1.0 (2014-02-XX)
--------------------------
-Moved fixUpUrl into its own file, called lib/proxies.js (#112) (TODO)
+Moved fixUpUrl into its own file, called lib/proxies.js (#112)
Fixed duplication of querystring parameter lookup (#111) (TODO)
Tried running Snowplow JS Tracker from PhoneGap (#107) (TODO)
Added tests for helpers.js (#96) (TODO)
From eb0b452a35066f6147154fda79a1c30eefa66175 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 26 Feb 2014 11:06:34 +0000
Subject: [PATCH 0016/1261] proxies.js now has helpers.js as a Browserify
dependency
---
src/js/lib/proxies.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/js/lib/proxies.js b/src/js/lib/proxies.js
index 24777c468..7bd17980f 100644
--- a/src/js/lib/proxies.js
+++ b/src/js/lib/proxies.js
@@ -52,7 +52,7 @@
matches = e.exec(url),
f = new RegExp('(?:^|&)' + name + '=([^&]*)'),
result = matches ? f.exec(matches[1]) : 0;
-
+console.log('matches:', matches)
return result ? decodeURIComponent(result[1]) : '';
}
From cd1fa05b3ea5adc9fb0dc5d0f5111e30700e5912 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 26 Feb 2014 11:08:51 +0000
Subject: [PATCH 0017/1261] Removed debug code from proxies.js
---
src/js/lib/proxies.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/js/lib/proxies.js b/src/js/lib/proxies.js
index 7bd17980f..24777c468 100644
--- a/src/js/lib/proxies.js
+++ b/src/js/lib/proxies.js
@@ -52,7 +52,7 @@
matches = e.exec(url),
f = new RegExp('(?:^|&)' + name + '=([^&]*)'),
result = matches ? f.exec(matches[1]) : 0;
-console.log('matches:', matches)
+
return result ? decodeURIComponent(result[1]) : '';
}
From ffee9a6bf7bedcdf51f3471f1421ea868b4fc02f Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 26 Feb 2014 17:10:12 +0000
Subject: [PATCH 0018/1261] Fixed duplication of querystring parameter lookup
(#111)
---
CHANGELOG | 2 +-
src/js/lib/proxies.js | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3ba2ad57a..700c63914 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,7 +11,7 @@ Added cache control to Grunt upload for full semantic version (#225)
Version 1.1.0 (2014-02-XX)
--------------------------
Moved fixUpUrl into its own file, called lib/proxies.js (#112)
-Fixed duplication of querystring parameter lookup (#111) (TODO)
+Fixed duplication of querystring parameter lookup (#111)
Tried running Snowplow JS Tracker from PhoneGap (#107) (TODO)
Added tests for helpers.js (#96) (TODO)
Added tests for detectors.js (#95) (TODO)
diff --git a/src/js/lib/proxies.js b/src/js/lib/proxies.js
index 24777c468..2787e3056 100644
--- a/src/js/lib/proxies.js
+++ b/src/js/lib/proxies.js
@@ -43,17 +43,17 @@
* TODO: it would be nice to generalise this and/or move into the ETL phase.
*/
object.fixupUrl = function (hostName, href, referrer) {
+
/*
* Extract parameter from URL
*/
function getParameter(url, name) {
// scheme : // [username [: password] @] hostname [: port] [/ [path] [? query] [# fragment]]
- var e = new RegExp('^(?:https?|ftp)(?::/*(?:[^?]+)[?])([^#]+)'),
+ var e = new RegExp('^(?:https?|ftp)(?::/*(?:[^?]+))([?][^#]+)'),
matches = e.exec(url),
- f = new RegExp('(?:^|&)' + name + '=([^&]*)'),
- result = matches ? f.exec(matches[1]) : 0;
+ result = helpers.fromQuerystring(name, matches[1]);
- return result ? decodeURIComponent(result[1]) : '';
+ return result;
}
if (hostName === 'translate.googleusercontent.com') { // Google
From 58b110560b344507309569d8980f1f6fa58ec639 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 26 Feb 2014 17:13:52 +0000
Subject: [PATCH 0019/1261] Changed release month to March
---
CHANGELOG | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 700c63914..923cf849b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,7 +8,7 @@ Added guard to prevent document size field from being set as "NaNxNaN" (#220)
Fixed Grunt publish tasks to build sp.js as well as upload it to S3 (#224)
Added cache control to Grunt upload for full semantic version (#225)
-Version 1.1.0 (2014-02-XX)
+Version 1.1.0 (2014-03-XX)
--------------------------
Moved fixUpUrl into its own file, called lib/proxies.js (#112)
Fixed duplication of querystring parameter lookup (#111)
From 2c1b288a8f2fbed38eee991a2ded6c1c50f58524 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 27 Feb 2014 09:37:04 +0000
Subject: [PATCH 0020/1261] Replaced cookie.js with browser-cookie-lite (#88)
---
CHANGELOG | 2 +-
package.json | 3 ++-
src/js/lib/detectors.js | 5 +++--
src/js/tracker.js | 16 ++++++++--------
4 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 923cf849b..a987ee046 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -15,7 +15,7 @@ Fixed duplication of querystring parameter lookup (#111)
Tried running Snowplow JS Tracker from PhoneGap (#107) (TODO)
Added tests for helpers.js (#96) (TODO)
Added tests for detectors.js (#95) (TODO)
-Replaced cookie.js with browser-cookie-lite (#88) (TODO)
+Replaced cookie.js with browser-cookie-lite (#88)
Added ad conversion tracking (#60) (TODO)
Added ad click tracking (#59) (TODO)
Added initial localStorage support for intermittent offline beacons (#24) (TODO)
diff --git a/package.json b/package.json
index 7f503ee68..5b92a8801 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,8 @@
"jstimezonedetect": "~1.0.5",
"JSON": "~1.0.0",
"sha1": "git://github.com/pvorb/node-sha1.git#v1.0.0",
- "grunt-lodash": "~0.3.0"
+ "grunt-lodash": "~0.3.0",
+ "browser-cookie-lite": "~0.3.1"
},
"contributors": [
"Alex Dean",
diff --git a/src/js/lib/detectors.js b/src/js/lib/detectors.js
index df2c1c0fb..5338db5f5 100644
--- a/src/js/lib/detectors.js
+++ b/src/js/lib/detectors.js
@@ -40,6 +40,7 @@
cookie = require('./cookie'),
murmurhash3_32_gc = require('murmurhash').v3,
tz = require('jstimezonedetect').jstz.determine(),
+ cookie = require('browser-cookie-lite'),
object = typeof exports !== 'undefined' ? exports : this, // For eventual node.js environment support
@@ -81,8 +82,8 @@
var cookieName = testCookieName || 'testcookie';
if (lodash.isUndefined(navigatorAlias.cookieEnabled)) {
- cookie.setCookie(cookieName, '1');
- return cookie.getCookie(cookieName) === '1' ? '1' : '0';
+ cookie.cookie(cookieName, '1');
+ return cookie.cookie(cookieName) === '1' ? '1' : '0';
}
return navigatorAlias.cookieEnabled ? '1' : '0';
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 3283a8d01..990cc347b 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -38,7 +38,7 @@
lodash = require('./lib/lodash'),
helpers = require('./lib/helpers'),
proxies = require('./lib/proxies'),
- cookie = require('./lib/cookie'),
+ cookie = require('browser-cookie-lite'),
detectors = require('./lib/detectors'),
payload = require('./payload'),
json2 = require('JSON'),
@@ -369,7 +369,7 @@
* Cookie getter.
*/
function getSnowplowCookieValue(cookieName) {
- return cookie.getCookie(getSnowplowCookieName(cookieName));
+ return cookie.cookie(getSnowplowCookieName(cookieName));
}
/*
@@ -449,7 +449,7 @@
* or when there is a new visit or a new page view
*/
function setDomainUserIdCookie(_domainUserId, createTs, visitCount, nowTs, lastVisitTs) {
- cookie.setCookie(getSnowplowCookieName('id'), _domainUserId + '.' + createTs + '.' + visitCount + '.' + nowTs + '.' + lastVisitTs, configVisitorCookieTimeout, configCookiePath, configCookieDomain);
+ cookie.cookie(getSnowplowCookieName('id'), _domainUserId + '.' + createTs + '.' + visitCount + '.' + nowTs + '.' + lastVisitTs, configVisitorCookieTimeout, configCookiePath, configCookieDomain);
}
/*
@@ -531,13 +531,13 @@
idname = getSnowplowCookieName('id'),
sesname = getSnowplowCookieName('ses'),
id = loadDomainUserIdCookie(),
- ses = getSnowplowCookieValue('ses'), // aka cookie.getCookieValue(sesname)
+ ses = getSnowplowCookieValue('ses'), // aka cookie.cookie(sesname)
currentUrl = configCustomUrl || locationHrefAlias,
featurePrefix;
if (configDoNotTrack) {
- cookie.setCookie(idname, '', -1, configCookiePath, configCookieDomain);
- cookie.setCookie(sesname, '', -1, configCookiePath, configCookieDomain);
+ cookie.cookie(idname, '', -1, configCookiePath, configCookieDomain);
+ cookie.cookie(sesname, '', -1, configCookiePath, configCookieDomain);
return '';
}
@@ -591,7 +591,7 @@
// Update cookies
setDomainUserIdCookie(_domainUserId, createTs, visitCount, nowTs, lastVisitTs);
- cookie.setCookie(sesname, '*', configSessionCookieTimeout, configCookiePath, configCookieDomain);
+ cookie.cookie(sesname, '*', configSessionCookieTimeout, configCookiePath, configCookieDomain);
return request;
}
@@ -1401,7 +1401,7 @@
* @param string cookieName Name of the cookie whose value will be assigned to businessUserId
*/
setUserIdFromCookie: function(cookieName) {
- businessUserId = cookie.getCookie(cookieName);
+ businessUserId = cookie.cookie(cookieName);
},
/**
From 57e62c85bd6b7df09b5ca623e57bdfc19437433e Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 27 Feb 2014 09:38:08 +0000
Subject: [PATCH 0021/1261] Deleted cookie.js
---
src/js/lib/cookie.js | 68 --------------------------------------------
1 file changed, 68 deletions(-)
delete mode 100644 src/js/lib/cookie.js
diff --git a/src/js/lib/cookie.js b/src/js/lib/cookie.js
deleted file mode 100644
index 0b57e33f0..000000000
--- a/src/js/lib/cookie.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * JavaScript tracker for Snowplow: cookie.js
- *
- * Significant portions copyright 2010 Anthon Pang. Remainder copyright
- * 2012-2014 Snowplow Analytics Ltd. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of Anthon Pang nor Snowplow Analytics Ltd nor the
- * names of their contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-;(function() {
-
- var object = typeof exports !== 'undefined' ? exports : this; // For eventual node.js environment support
-
- /*
- * Get cookie value
- */
- object.getCookie = function (cookieName) {
- var cookiePattern = new RegExp('(^|;)[ ]*' + cookieName + '=([^;]*)'),
- cookieMatch = cookiePattern.exec(document.cookie);
-
- return cookieMatch ? decodeURIComponent(cookieMatch[2]) : 0;
- }
-
- /*
- * Set cookie value
- */
- object.setCookie = function (cookieName, value, msToExpire, path, domain, secure) {
- var expiryDate;
-
- // relative time to expire in milliseconds
- if (msToExpire) {
- expiryDate = new Date();
- expiryDate.setTime(expiryDate.getTime() + msToExpire);
- }
-
- document.cookie = cookieName + '=' + encodeURIComponent(value) +
- (msToExpire ? ';expires=' + expiryDate.toGMTString() : '') +
- ';path=' + (path || '/') +
- (domain ? ';domain=' + domain : '') +
- (secure ? ';secure' : '');
- }
-
-}());
From 453de293e87e6e9af81ec5323643fd360bc77e9f Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 27 Feb 2014 17:08:04 +0000
Subject: [PATCH 0022/1261] Added ad click tracking (#59)
---
CHANGELOG | 2 +-
src/js/tracker.js | 17 ++++++++++++++++-
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index a987ee046..e09a046a7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,7 +17,7 @@ Added tests for helpers.js (#96) (TODO)
Added tests for detectors.js (#95) (TODO)
Replaced cookie.js with browser-cookie-lite (#88)
Added ad conversion tracking (#60) (TODO)
-Added ad click tracking (#59) (TODO)
+Added ad click tracking (#59)
Added initial localStorage support for intermittent offline beacons (#24) (TODO)
Added new trackAdImpression, mapping to unstructured event (#13) (TODO)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 990cc347b..81db46bf8 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -850,6 +850,18 @@
}
// TODO: add in ad clicks and conversions
+ function logAdClick(bannerId, campaignId, advertiserId, userId, target_url, context) {
+ var sb = payload.payloadBuilder(configEncodeBase64);
+ sb.add('e', 'ac'); // 'ac' for Ad Click
+ sb.add('ad_ba', bannerId);
+ sb.add('ad_ca', campaignId)
+ sb.add('ad_ad', advertiserId);
+ sb.add('ad_uid', userId);
+ sb.add('ad_url', target_url);
+ sb.addJson('cx', 'co', context);
+ request = getRequest(sb, 'ad_click');
+ sendRequest(request, configTrackerPause);
+ }
/*
* Browser prefix
@@ -1607,9 +1619,12 @@
console.log("Snowplow: trackImpression is deprecated. When version 1.1.0 is released, switch to trackAdImpression.");
}
logImpression(bannerId, campaignId, advertiserId, userId, context);
- }
+ },
// TODO: add in ad clicks and conversions
+ trackAdClick: function(bannerId, campaignId, advertiserId, userId, target_url, context) {
+ logAdClick(bannerId, campaignId, advertiserId, userId, target_url, context);
+ }
};
}
From 4ffff702f66ae2a1a741f38d63b7a3329d354ef7 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 27 Feb 2014 17:11:39 +0000
Subject: [PATCH 0023/1261] Removed references to referral cookie (#118)
---
CHANGELOG | 1 +
src/js/tracker.js | 12 ------------
2 files changed, 1 insertion(+), 12 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index e09a046a7..c99456016 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,7 @@ Added ad conversion tracking (#60) (TODO)
Added ad click tracking (#59)
Added initial localStorage support for intermittent offline beacons (#24) (TODO)
Added new trackAdImpression, mapping to unstructured event (#13) (TODO)
+Removed references to referral cookie (#118)
Version 1.0.1 (2014-04-09)
--------------------------
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 81db46bf8..ea1bbfbe3 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -151,9 +151,6 @@
// Life of the session cookie (in milliseconds)
configSessionCookieTimeout = 1800000, // 30 minutes
- // Life of the referral cookie (in milliseconds)
- configReferralCookieTimeout = 15768000000, // 6 months
-
// Enable Base64 encoding for unstructured events
configEncodeBase64 = true,
@@ -1256,15 +1253,6 @@
configSessionCookieTimeout = timeout * 1000;
},
- /**
- * Set referral cookie timeout (in seconds)
- *
- * @param int timeout
- */
- setReferralCookieTimeout: function (timeout) {
- configReferralCookieTimeout = timeout * 1000;
- },
-
/**
* @param number seed The seed used for MurmurHash3
*/
From dca5ba60dec3472bf3eadca3619fa9246c25300a Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Mon, 3 Mar 2014 10:35:45 +0000
Subject: [PATCH 0024/1261] Added logAdImpression
---
src/js/tracker.js | 60 ++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 54 insertions(+), 6 deletions(-)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index ea1bbfbe3..e551f70c1 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -846,20 +846,64 @@
sendRequest(request, configTrackerPause);
}
+ function addAdvertisingWideFields(sb, advertiserId, costModel, campaignId) {
+ sb.add('ad_ad', advertiserId);
+ sb.add('ad_cm', costModel);
+ sb.add('ad_ca', campaignId);
+ request = getRequest(sb);
+ sendRequest(request, configTrackerPause);
+ }
+
+ function logAdImpression(impressionId, costIfCpm, bannerId, zoneId, advertiserId, costModel, campaignId, context) {
+ var sb = payload.payloadBuilder(configEncodeBase64);
+ sb.add('e', 'ai'); // 'ai' for Ad Impression
+ sb.add('ad_im', impressionId);
+ sb.add('ad_cpm', costIfCpm);
+ sb.add('ad_ba', bannerId);
+ sb.add('ad_zo', zoneId);
+ sb.add('ad_ad', advertiserId);
+ sb.add('ad_ca', campaignId);
+ sb.add('ad_uid', userId);
+ sb.addJson('cx', 'co', context);
+ request = getRequest(sb, 'ad_impression');
+ sendRequest(request, configTrackerPause);
+ }
+
+ function logAdImpression(properties, context) {
+ var sb = payload.payloadBuilder(configEncodeBase64);
+ sb.add('e', 'ai'); // 'ai' for Ad Impression
+ sb.addJson('ai_px', 'ai_pr', properties);
+ sb.addJson('cx', 'co', context);
+ request = getRequest(sb, 'ad_impression');
+ sendRequest(request, configTrackerPause);
+ }
+
// TODO: add in ad clicks and conversions
- function logAdClick(bannerId, campaignId, advertiserId, userId, target_url, context) {
+ function logAdClick(clickId, costIfCpc, targetUrl, bannerId, zoneId, impressionId, advertiserId, costModel, campaignId, context) {
var sb = payload.payloadBuilder(configEncodeBase64);
sb.add('e', 'ac'); // 'ac' for Ad Click
+ sb.add('ad_cpc', costIfCpc);
+ sb.add('ad_url', targetUrl);
sb.add('ad_ba', bannerId);
- sb.add('ad_ca', campaignId)
+ sb.add('ad_zo', zoneId);
+ sb.add('ad_im', impressionId);
sb.add('ad_ad', advertiserId);
+ sb.add('ad_ca', campaignId);
sb.add('ad_uid', userId);
- sb.add('ad_url', target_url);
sb.addJson('cx', 'co', context);
request = getRequest(sb, 'ad_click');
sendRequest(request, configTrackerPause);
}
+ function logAdClick(properties, context) {
+ var sb = payload.payloadBuilder(configEncodeBase64);
+ sb.add('e', 'ac'); // 'ac' for Ad Click
+ sb.addJson('ai_px', 'ai_pr', properties);
+ sb.addJson('cx', 'co', context);
+ request = getRequest(sb, 'ad_clik');
+ sendRequest(request, configTrackerPause);
+ }
+
/*
* Browser prefix
*/
@@ -1609,9 +1653,13 @@
logImpression(bannerId, campaignId, advertiserId, userId, context);
},
- // TODO: add in ad clicks and conversions
- trackAdClick: function(bannerId, campaignId, advertiserId, userId, target_url, context) {
- logAdClick(bannerId, campaignId, advertiserId, userId, target_url, context);
+ // TODO: comments for ad tracking functions
+ trackAdImpression: function(impressionId, costIfCpm, bannerId, zoneId, advertiserId, costModel, campaignId, context) {
+ logAdImpression(impressionId, costIfCpm, bannerId, zoneId, advertiserId, costModel, campaignId, context);
+ }
+
+ trackAdClick: function(clickId, costIfCpc, targetUrl, bannerId, zoneId, impressionId, advertiserId, costModel, campaignId, context) {
+ logAdClick(clickId, costIfCpc, targetUrl, bannerId, zoneId, impressionId, advertiserId, costModel, campaignId, context);
}
};
}
From 235efcea17ced64fcc3b7b7a127aa82aa85c6165 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Mon, 3 Mar 2014 12:39:39 +0000
Subject: [PATCH 0025/1261] Added ad impression, ad click, and ad conversion
tracking (#13) (#60) (#59)
---
CHANGELOG | 4 +-
src/js/tracker.js | 106 +++++++++++++++++++---------------------------
2 files changed, 45 insertions(+), 65 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index c99456016..d9dd0e49b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,10 +16,10 @@ Tried running Snowplow JS Tracker from PhoneGap (#107) (TODO)
Added tests for helpers.js (#96) (TODO)
Added tests for detectors.js (#95) (TODO)
Replaced cookie.js with browser-cookie-lite (#88)
-Added ad conversion tracking (#60) (TODO)
+Added ad conversion tracking (#60)
Added ad click tracking (#59)
Added initial localStorage support for intermittent offline beacons (#24) (TODO)
-Added new trackAdImpression, mapping to unstructured event (#13) (TODO)
+Added new trackAdImpression, mapping to unstructured event (#13)
Removed references to referral cookie (#118)
Version 1.0.1 (2014-04-09)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index e551f70c1..15ebb379f 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -846,64 +846,6 @@
sendRequest(request, configTrackerPause);
}
- function addAdvertisingWideFields(sb, advertiserId, costModel, campaignId) {
- sb.add('ad_ad', advertiserId);
- sb.add('ad_cm', costModel);
- sb.add('ad_ca', campaignId);
- request = getRequest(sb);
- sendRequest(request, configTrackerPause);
- }
-
- function logAdImpression(impressionId, costIfCpm, bannerId, zoneId, advertiserId, costModel, campaignId, context) {
- var sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', 'ai'); // 'ai' for Ad Impression
- sb.add('ad_im', impressionId);
- sb.add('ad_cpm', costIfCpm);
- sb.add('ad_ba', bannerId);
- sb.add('ad_zo', zoneId);
- sb.add('ad_ad', advertiserId);
- sb.add('ad_ca', campaignId);
- sb.add('ad_uid', userId);
- sb.addJson('cx', 'co', context);
- request = getRequest(sb, 'ad_impression');
- sendRequest(request, configTrackerPause);
- }
-
- function logAdImpression(properties, context) {
- var sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', 'ai'); // 'ai' for Ad Impression
- sb.addJson('ai_px', 'ai_pr', properties);
- sb.addJson('cx', 'co', context);
- request = getRequest(sb, 'ad_impression');
- sendRequest(request, configTrackerPause);
- }
-
- // TODO: add in ad clicks and conversions
- function logAdClick(clickId, costIfCpc, targetUrl, bannerId, zoneId, impressionId, advertiserId, costModel, campaignId, context) {
- var sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', 'ac'); // 'ac' for Ad Click
- sb.add('ad_cpc', costIfCpc);
- sb.add('ad_url', targetUrl);
- sb.add('ad_ba', bannerId);
- sb.add('ad_zo', zoneId);
- sb.add('ad_im', impressionId);
- sb.add('ad_ad', advertiserId);
- sb.add('ad_ca', campaignId);
- sb.add('ad_uid', userId);
- sb.addJson('cx', 'co', context);
- request = getRequest(sb, 'ad_click');
- sendRequest(request, configTrackerPause);
- }
-
- function logAdClick(properties, context) {
- var sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', 'ac'); // 'ac' for Ad Click
- sb.addJson('ai_px', 'ai_pr', properties);
- sb.addJson('cx', 'co', context);
- request = getRequest(sb, 'ad_clik');
- sendRequest(request, configTrackerPause);
- }
-
/*
* Browser prefix
*/
@@ -1655,13 +1597,51 @@
// TODO: comments for ad tracking functions
trackAdImpression: function(impressionId, costIfCpm, bannerId, zoneId, advertiserId, costModel, campaignId, context) {
- logAdImpression(impressionId, costIfCpm, bannerId, zoneId, advertiserId, costModel, campaignId, context);
- }
+ trackUnstructEvent('ad_impression',
+ {
+ impression_id: impressionId,
+ cost_if_cpm: costIfCpm,
+ banner_id: bannerId,
+ zone_id: zoneId,
+ advertiser_id: advertiserId,
+ cost_model: costModel,
+ campaign_id: campaignId
+ },
+ context);
+ },
+
+ trackAdclick: function(clickId, costIfCpc, targetUrl, bannerId, zoneId, impressionId, advertiserId, costModel, campaignId, context) {
+ trackUnstructEvent('ad_click',
+ {
+ click_id: clickId,
+ cost_if_cpc: costIfCpc,
+ target_url: targetUrl,
+ banner_id: bannerId,
+ zone_id: zoneId,
+ impression_id: impressionId,
+ advertiser_id: advertiserId,
+ cost_model: costModel,
+ campaign_id: campaignId
+ },
+ context);
+ },
- trackAdClick: function(clickId, costIfCpc, targetUrl, bannerId, zoneId, impressionId, advertiserId, costModel, campaignId, context) {
- logAdClick(clickId, costIfCpc, targetUrl, bannerId, zoneId, impressionId, advertiserId, costModel, campaignId, context);
+ trackAdConversion: function(conversionId, costIfCpa, category, action, property, initialValue, advertiserId, costModel, campaignId, context) {
+ trackUnstructEvent('ad_conversion',
+ {
+ conversion_id: conversionId,
+ cost_if_cpa: costIfCpa,
+ category: category,
+ action: action,
+ property: property,
+ initial_value: initialValue,
+ advertiser_id: advertiserId,
+ cost_model: costModel,
+ campaign_id: campaignId
+ },
+ context)
}
- };
+ }
}
}());
From 1702d2a34199dabad005002cb3751888fdbdd308 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Mon, 3 Mar 2014 12:43:30 +0000
Subject: [PATCH 0026/1261] getRequest now called with only one argument
---
src/js/tracker.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 15ebb379f..fb8456797 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -632,7 +632,7 @@
sb.add('e', 'pv'); // 'pv' for Page View
sb.add('page', pageTitle);
sb.addJson('cx', 'co', context);
- var request = getRequest(sb, 'pageView');
+ var request = getRequest(sb);
sendRequest(request, configTrackerPause);
// Send ping (to log that user has stayed on page)
@@ -695,7 +695,7 @@
sb.addRaw('pp_may', maxYOffset); // Global
sb.addJson('cx', 'co', context);
resetMaxScrolls();
- var request = getRequest(sb, 'pagePing');
+ var request = getRequest(sb);
sendRequest(request, configTrackerPause);
}
@@ -718,7 +718,7 @@
sb.add('se_pr', property);
sb.add('se_va', value);
sb.addJson('cx', 'co', context);
- var request = getRequest(sb, 'structEvent');
+ request = getRequest(sb);
sendRequest(request, configTrackerPause);
}
From 930a8ad4610f860e4ef71e65b19af0271a02ffb2 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Mon, 3 Mar 2014 13:17:14 +0000
Subject: [PATCH 0027/1261] getRequest now always called with only one argument
---
src/js/tracker.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index fb8456797..1409a2422 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -735,7 +735,7 @@
sb.add('ue_na', name);
sb.addJson('ue_px', 'ue_pr', properties);
sb.addJson('cx', 'co', context);
- var request = getRequest(sb, 'unstructEvent');
+ request = getRequest(sb);
sendRequest(request, configTrackerPause);
}
@@ -767,7 +767,7 @@
sb.add('tr_co', country);
sb.add('tr_cu', currency);
sb.addJson('cx', 'co', context);
- var request = getRequest(sb, 'transaction');
+ var request = getRequest(sb);
sendRequest(request, configTrackerPause);
}
@@ -795,7 +795,7 @@
sb.add('ti_qu', quantity);
sb.add('ti_cu', currency);
sb.addJson('cx', 'co', context);
- var request = getRequest(sb, 'transactionItem');
+ var request = getRequest(sb);
sendRequest(request, configTrackerPause);
}
@@ -817,7 +817,7 @@
var sb = payload.payloadBuilder(configEncodeBase64);
sb.add('e', linkType);
sb.add('t_url', purify(url));
- var request = getRequest(sb, 'link');
+ var request = getRequest(sb);
sendRequest(request, configTrackerPause);
}
@@ -842,7 +842,7 @@
sb.add('ad_ad', advertiserId);
sb.add('ad_uid', userId);
sb.addJson('cx', 'co', context);
- var request = getRequest(sb, 'impression');
+ request = getRequest(sb);
sendRequest(request, configTrackerPause);
}
From c50dd36b5b83ddb8fdc81659871186bb81587ad9 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Mon, 3 Mar 2014 13:28:04 +0000
Subject: [PATCH 0028/1261] Corrected trackUnstructEvent to logUnstructEvent
---
src/js/tracker.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 1409a2422..3c63479de 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -1597,7 +1597,7 @@
// TODO: comments for ad tracking functions
trackAdImpression: function(impressionId, costIfCpm, bannerId, zoneId, advertiserId, costModel, campaignId, context) {
- trackUnstructEvent('ad_impression',
+ logUnstructEvent('ad_impression',
{
impression_id: impressionId,
cost_if_cpm: costIfCpm,
@@ -1610,8 +1610,8 @@
context);
},
- trackAdclick: function(clickId, costIfCpc, targetUrl, bannerId, zoneId, impressionId, advertiserId, costModel, campaignId, context) {
- trackUnstructEvent('ad_click',
+ trackAdClick: function(clickId, costIfCpc, targetUrl, bannerId, zoneId, impressionId, advertiserId, costModel, campaignId, context) {
+ logUnstructEvent('ad_click',
{
click_id: clickId,
cost_if_cpc: costIfCpc,
@@ -1627,7 +1627,7 @@
},
trackAdConversion: function(conversionId, costIfCpa, category, action, property, initialValue, advertiserId, costModel, campaignId, context) {
- trackUnstructEvent('ad_conversion',
+ logUnstructEvent('ad_conversion',
{
conversion_id: conversionId,
cost_if_cpa: costIfCpa,
From 7cbf5d800c232b495677c0c29befaa5645df53e5 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Mon, 3 Mar 2014 14:59:10 +0000
Subject: [PATCH 0029/1261] Added localStorageAccessible in preparation for
adding localStorage support for intermittent offline beacons
---
src/js/lib/detectors.js | 19 +++++++++++++++++++
src/js/tracker.js | 4 ++--
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/js/lib/detectors.js b/src/js/lib/detectors.js
index 5338db5f5..75e6325bf 100644
--- a/src/js/lib/detectors.js
+++ b/src/js/lib/detectors.js
@@ -75,6 +75,25 @@
}
}
+ /*
+ * Checks whether localStorage is accessible
+ * sets and removes an item to handle private IOS5 browsing
+ * (http://git.io/jFB2Xw)
+ */
+ object.localStorageAccessible = function() {
+ var mod = 'modernizr';
+ if (!object.hasLocalStorage()) {
+ return false;
+ }
+ try {
+ windowAlias.localStorage.setItem(mod, mod);
+ windowAlias.localStorage.removeItem(mod);
+ return true;
+ } catch(e) {
+ return false;
+ }
+ }
+
/*
* Does browser have cookies enabled (for this site)?
*/
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 3c63479de..8e9d7ff4b 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -333,7 +333,7 @@
var image = new Image(1, 1);
- // Let's chec that we have a Url to ping
+ // Let's check that we have a Url to ping
if (configCollectorUrl === null) {
throw "No Snowplow collector configured, cannot track";
}
@@ -1597,7 +1597,7 @@
// TODO: comments for ad tracking functions
trackAdImpression: function(impressionId, costIfCpm, bannerId, zoneId, advertiserId, costModel, campaignId, context) {
- logUnstructEvent('ad_impression',
+ logUnstructEvent('ad_impression',
{
impression_id: impressionId,
cost_if_cpm: costIfCpm,
From 0d5779a4ff074534e66c37d8bf30d87b119a7b6d Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Mon, 3 Mar 2014 15:45:40 +0000
Subject: [PATCH 0030/1261] Added initial localStorage suport for intermittent
offline beacons (#24)
---
CHANGELOG | 2 +-
src/js/tracker.js | 96 +++++++++++++++++++++++++++++++++++++----------
2 files changed, 77 insertions(+), 21 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index d9dd0e49b..c78f916fc 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,7 +18,7 @@ Added tests for detectors.js (#95) (TODO)
Replaced cookie.js with browser-cookie-lite (#88)
Added ad conversion tracking (#60)
Added ad click tracking (#59)
-Added initial localStorage support for intermittent offline beacons (#24) (TODO)
+Added initial localStorage support for intermittent offline beacons (#24)
Added new trackAdImpression, mapping to unstructured event (#13)
Removed references to referral cookie (#118)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 8e9d7ff4b..fdb7be832 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -205,7 +205,81 @@
// Ecommerce transaction data
// Will be committed, sent and emptied by a call to trackTrans.
- ecommerceTransaction = ecommerceTransactionTemplate();
+ ecommerceTransaction = ecommerceTransactionTemplate(),
+
+ // Detect whether we have localStorage available
+ hasLocalStorage = detectors.localStorageAccessible(),
+ executingQueue = false,
+ imageQueue;
+
+ if (hasLocalStorage) {
+ // Catch and JSON parse errors that might be thrown
+ try {
+ imageQueue = json2.parse(localStorage.getItem('snaqImageQueue'));
+ }
+ catch(e) {}
+ }
+
+ // Initialize to and empty array if we didn't get anything out of localStorage
+ if (typeof imageQueue === 'undefined' || imageQueue == null) {
+ imageQueue = [];
+ }
+
+ /*
+ * Queue an image beacon for submission to the collector.
+ * If we're not processing the queue, we'll start.
+ */
+ function queueImage(request) {
+ imageQueue.push(request);
+ if (hasLocalStorage) {
+ localStorage.setItem('snaqImageQueue', json2.stringify(imageQueue));
+ }
+
+ if (!executingQueue) {
+ executeQueue();
+ }
+ }
+
+ /*
+ * Run through the queue of image beacons, sending them one at a time.
+ * Stops processing when we run out of queued requests, or we get an error.
+ */
+ function executeQueue() {
+ if (imageQueue.length < 1) {
+ executingQueue = false;
+ return;
+ }
+
+ executingQueue = true;
+ var nextRequest = imageQueue[0];
+
+ /*
+ * Send image request to the Snowplow Collector using GET.
+ * The Collecor serves a transparent, single pixel (1x1) GIF
+ */
+ var image = new Image(1,1);
+
+ // Let's check hat we have a Url to ping
+ if (configCollectorUrl === null) {
+ throw "No Snowplow collector configured, cannot track";
+ }
+
+ // Okay? Let's proceed.
+ image.onload = function() {
+ // We succeeded, let's remove this request from the queue
+ imageQueue.shift();
+ if (hasLocalStorage) {
+ localStorage.setItem('snaqImageQueue', json2.stringify(imageQueue));
+ }
+ executeQueue();
+ }
+
+ image.onerror = function() {
+ executingQueue = false;
+ }
+
+ image.src = configCollectorUrl + nextRequest;
+ }
/**
* Determines how to build our collector URL,
@@ -325,24 +399,6 @@
return false;
}
- /*
- * Send image request to the Snowplow Collector using GET.
- * The Collector serves a transparent, single pixel (1x1) GIF
- */
- function getImage(request) {
-
- var image = new Image(1, 1);
-
- // Let's check that we have a Url to ping
- if (configCollectorUrl === null) {
- throw "No Snowplow collector configured, cannot track";
- }
-
- // Okay? Let's proceed.
- image.onload = function () { };
- image.src = configCollectorUrl + request;
- }
-
/*
* Send request
*/
@@ -350,7 +406,7 @@
var now = new Date();
if (!configDoNotTrack) {
- getImage(request);
+ queueImage(request);
mutSnowplowState.expireDateTime = now.getTime() + delay;
}
}
From c70f79c8584634858ac17a7366f5e0dcd088bc69 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Mon, 3 Mar 2014 16:14:10 +0000
Subject: [PATCH 0031/1261] Changed indentation and fixed typos
---
src/js/lib/proxies.js | 8 ++++----
src/js/tracker.js | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/js/lib/proxies.js b/src/js/lib/proxies.js
index 2787e3056..a6919d2cd 100644
--- a/src/js/lib/proxies.js
+++ b/src/js/lib/proxies.js
@@ -56,15 +56,15 @@
return result;
}
- if (hostName === 'translate.googleusercontent.com') { // Google
+ if (hostName === 'translate.googleusercontent.com') { // Google
if (referrer === '') {
referrer = href;
}
href = getParameter(href, 'u');
hostName = helpers.getHostName(href);
- } else if (hostName === 'cc.bingj.com' || // Bing
- hostName === 'webcache.googleusercontent.com' || // Google
- hostName.slice(0, 5) === '74.6.') { // Yahoo (via Inktomi 74.6.0.0/16)
+ } else if (hostName === 'cc.bingj.com' || // Bing
+ hostName === 'webcache.googleusercontent.com' || // Google
+ hostName.slice(0, 5) === '74.6.') { // Yahoo (via Inktomi 74.6.0.0/16)
href = document.links[0].href;
hostName = helpers.getHostName(href);
}
diff --git a/src/js/tracker.js b/src/js/tracker.js
index fdb7be832..38055f21b 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -255,11 +255,11 @@
/*
* Send image request to the Snowplow Collector using GET.
- * The Collecor serves a transparent, single pixel (1x1) GIF
+ * The Collector serves a transparent, single pixel (1x1) GIF
*/
var image = new Image(1,1);
- // Let's check hat we have a Url to ping
+ // Let's check that we have a Url to ping
if (configCollectorUrl === null) {
throw "No Snowplow collector configured, cannot track";
}
From e2a70207cc2903ee2c8db8c26ed83a674a362c96 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Mon, 3 Mar 2014 17:04:20 +0000
Subject: [PATCH 0032/1261] Moved the image queue into its own module,
in_queue.js
---
src/js/{queue.js => in_queue.js} | 0
src/js/out_queue.js | 114 +++++++++++++++++++++++++++++++
src/js/snowplow.js | 2 +-
src/js/tracker.js | 79 +--------------------
tests/{queue.js => in_queue.js} | 8 +--
5 files changed, 122 insertions(+), 81 deletions(-)
rename src/js/{queue.js => in_queue.js} (100%)
create mode 100644 src/js/out_queue.js
rename tests/{queue.js => in_queue.js} (92%)
diff --git a/src/js/queue.js b/src/js/in_queue.js
similarity index 100%
rename from src/js/queue.js
rename to src/js/in_queue.js
diff --git a/src/js/out_queue.js b/src/js/out_queue.js
new file mode 100644
index 000000000..536e123f3
--- /dev/null
+++ b/src/js/out_queue.js
@@ -0,0 +1,114 @@
+/*
+ * JavaScript tracker for Snowplow: out_queue.js
+ *
+ * Significant portions copyright 2010 Anthon Pang. Remainder copyright
+ * 2012-2014 Snowplow Analytics Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Anthon Pang nor Snowplow Analytics Ltd nor the
+ * names of their contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+;(function() {
+
+ var
+ json2 = require('JSON'),
+ localStorageAccessible = require('./lib/detectors').localStorageAccessible(),
+ object = typeof exports !== 'undefined' ? exports : this, // For eventual node.js environment support
+
+ executingQueue = false,
+ imageQueue;
+
+ if (localStorageAccessible) {
+ // Catch any JSON parse errors that might be thrown
+ try {
+ imageQueue = json2.parse(localStorage.getItem('snaqImageQueue'));
+ }
+ catch(e) {}
+ }
+
+ // Initialize to and empty array if we didn't get anything out of localStorage
+ if (typeof imageQueue === 'undefined' || imageQueue == null) {
+ imageQueue = [];
+ }
+
+ /*
+ * Queue an image beacon for submission to the collector.
+ * If we're not processing the queue, we'll start.
+ */
+ object.queueImage = function(request, configCollectorUrl) {
+ imageQueue.push(request);
+ if (localStorageAccessible) {
+ localStorage.setItem('snaqImageQueue', json2.stringify(imageQueue));
+ }
+
+ if (!executingQueue) {
+ executeQueue(configCollectorUrl);
+ }
+ }
+
+ /*
+ * Run through the queue of image beacons, sending them one at a time.
+ * Stops processing when we run out of queued requests, or we get an error.
+ */
+ function executeQueue(configCollectorUrl) {
+ if (imageQueue.length < 1) {
+ executingQueue = false;
+ return;
+ }
+
+ executingQueue = true;
+ var nextRequest = imageQueue[0];
+
+ /*
+ * Send image request to the Snowplow Collector using GET.
+ * The Collector serves a transparent, single pixel (1x1) GIF
+ */
+ var image = new Image(1,1);
+
+ // Let's check that we have a Url to ping
+ if (configCollectorUrl === null) {
+ throw "No Snowplow collector configured, cannot track";
+ }
+
+ // Okay? Let's proceed.
+ image.onload = function() {
+ // We succeeded, let's remove this request from the queue
+ imageQueue.shift();
+ if (localStorageAccessible) {
+ localStorage.setItem('snaqImageQueue', json2.stringify(imageQueue));
+ }
+ executeQueue(configCollectorUrl);
+ }
+
+ image.onerror = function() {
+ executingQueue = false;
+ }
+
+ image.src = configCollectorUrl + nextRequest;
+ }
+
+}());
diff --git a/src/js/snowplow.js b/src/js/snowplow.js
index 4c5b13696..03e349fe3 100644
--- a/src/js/snowplow.js
+++ b/src/js/snowplow.js
@@ -77,7 +77,7 @@
var
tracker = require('./tracker'),
helpers = require('./lib/helpers'),
- queue = require('./queue'),
+ queue = require('./in_queue'),
object = typeof exports !== 'undefined' ? exports : this; // For eventual node.js environment support
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 38055f21b..177d03909 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -43,6 +43,7 @@
payload = require('./payload'),
json2 = require('JSON'),
sha1 = require('sha1'),
+ images = require('./out_queue'),
object = typeof exports !== 'undefined' ? exports : this; // For eventual node.js environment support
@@ -205,81 +206,7 @@
// Ecommerce transaction data
// Will be committed, sent and emptied by a call to trackTrans.
- ecommerceTransaction = ecommerceTransactionTemplate(),
-
- // Detect whether we have localStorage available
- hasLocalStorage = detectors.localStorageAccessible(),
- executingQueue = false,
- imageQueue;
-
- if (hasLocalStorage) {
- // Catch and JSON parse errors that might be thrown
- try {
- imageQueue = json2.parse(localStorage.getItem('snaqImageQueue'));
- }
- catch(e) {}
- }
-
- // Initialize to and empty array if we didn't get anything out of localStorage
- if (typeof imageQueue === 'undefined' || imageQueue == null) {
- imageQueue = [];
- }
-
- /*
- * Queue an image beacon for submission to the collector.
- * If we're not processing the queue, we'll start.
- */
- function queueImage(request) {
- imageQueue.push(request);
- if (hasLocalStorage) {
- localStorage.setItem('snaqImageQueue', json2.stringify(imageQueue));
- }
-
- if (!executingQueue) {
- executeQueue();
- }
- }
-
- /*
- * Run through the queue of image beacons, sending them one at a time.
- * Stops processing when we run out of queued requests, or we get an error.
- */
- function executeQueue() {
- if (imageQueue.length < 1) {
- executingQueue = false;
- return;
- }
-
- executingQueue = true;
- var nextRequest = imageQueue[0];
-
- /*
- * Send image request to the Snowplow Collector using GET.
- * The Collector serves a transparent, single pixel (1x1) GIF
- */
- var image = new Image(1,1);
-
- // Let's check that we have a Url to ping
- if (configCollectorUrl === null) {
- throw "No Snowplow collector configured, cannot track";
- }
-
- // Okay? Let's proceed.
- image.onload = function() {
- // We succeeded, let's remove this request from the queue
- imageQueue.shift();
- if (hasLocalStorage) {
- localStorage.setItem('snaqImageQueue', json2.stringify(imageQueue));
- }
- executeQueue();
- }
-
- image.onerror = function() {
- executingQueue = false;
- }
-
- image.src = configCollectorUrl + nextRequest;
- }
+ ecommerceTransaction = ecommerceTransactionTemplate();
/**
* Determines how to build our collector URL,
@@ -406,7 +333,7 @@
var now = new Date();
if (!configDoNotTrack) {
- queueImage(request);
+ images.queueImage(request, configCollectorUrl);
mutSnowplowState.expireDateTime = now.getTime() + delay;
}
}
diff --git a/tests/queue.js b/tests/in_queue.js
similarity index 92%
rename from tests/queue.js
rename to tests/in_queue.js
index 72bf93e55..b873b6e58 100644
--- a/tests/queue.js
+++ b/tests/in_queue.js
@@ -1,5 +1,5 @@
/*
- * JavaScript tracker for Snowplow: tests/queue.js
+ * JavaScript tracker for Snowplow: tests/in_queue.js
*
* Significant portions copyright 2010 Anthon Pang. Remainder copyright
* 2012-2014 Snowplow Analytics Ltd. All rights reserved.
@@ -35,8 +35,8 @@
define([
'intern!object',
'intern/chai!assert',
- 'intern/dojo/node!../src/js/queue'
-], function(registerSuite, assert, queue) {
+ 'intern/dojo/node!../src/js/in_queue'
+], function(registerSuite, assert, in_queue) {
var MockTracker = function () {
var attribute = 10;
@@ -55,7 +55,7 @@ define([
var mockTracker = MockTracker(),
snaq = [['increaseAttribute', 5]];
- snaq = new queue.AsyncQueueProxy(mockTracker, snaq);
+ snaq = new in_queue.AsyncQueueProxy(mockTracker, snaq);
registerSuite({
name: 'queue test',
From 5a8c3bba7ee7a0a5eca23301bc0403a4fdaba732 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Mon, 3 Mar 2014 17:15:12 +0000
Subject: [PATCH 0033/1261] Brought intern.js up to date with renaming of
queue.js
---
tests/intern.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/intern.js b/tests/intern.js
index 7d2d20b8d..b9dc71fd4 100644
--- a/tests/intern.js
+++ b/tests/intern.js
@@ -35,6 +35,6 @@
define({
// Non-functional test suites
-suites: ['tests/queue', 'tests/payload'],
+suites: ['tests/in_queue', 'tests/payload'],
});
From d0b36a0a94242c1bf125eba222945d1e45e80f42 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 4 Mar 2014 16:32:30 +0000
Subject: [PATCH 0034/1261] logLink now maps to an unstructured event
enableLinkTracking now takes array of CSS classes to exclude
---
CHANGELOG | 3 +-
src/js/tracker.js | 218 +++++++++++-----------------------------------
2 files changed, 51 insertions(+), 170 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index c78f916fc..380cdfc8a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,7 +20,8 @@ Added ad conversion tracking (#60)
Added ad click tracking (#59)
Added initial localStorage support for intermittent offline beacons (#24)
Added new trackAdImpression, mapping to unstructured event (#13)
-Removed references to referral cookie (#118)
+Removed references to referral cookie (#118)
+Implement enableLinkTracking support (#51) (TODO)
Version 1.0.1 (2014-04-09)
--------------------------
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 177d03909..fe73496cb 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -102,21 +102,6 @@
// Document title
configTitle = documentAlias.title,
- // Extensions to be treated as download links
- configDownloadExtensions = '7z|aac|ar[cj]|as[fx]|avi|bin|csv|deb|dmg|doc|exe|flv|gif|gz|gzip|hqx|jar|jpe?g|js|mp(2|3|4|e?g)|mov(ie)?|ms[ip]|od[bfgpst]|og[gv]|pdf|phps|png|ppt|qtm?|ra[mr]?|rpm|sea|sit|tar|t?bz2?|tgz|torrent|txt|wav|wm[av]|wpd||xls|xml|z|zip',
-
- // Hosts or alias(es) to not treat as outlinks
- configHostsAlias = [domainAlias],
-
- // HTML anchor element classes to not track
- configIgnoreClasses = [],
-
- // HTML anchor element classes to treat as downloads
- configDownloadClasses = [],
-
- // HTML anchor element classes to treat at outlinks
- configLinkClasses = [],
-
// Maximum delay to wait for web bug image to be fetched (in milliseconds)
configTrackerPause = 500,
@@ -126,7 +111,7 @@
// Recurring heart beat after initial ping (in milliseconds)
configHeartBeatTimer,
- // Disallow hash tags in URL
+ // Disallow hash tags in URL. TODO: Should this be set to true by default?
configDiscardHashTag,
// First-party cookie name prefix
@@ -288,44 +273,6 @@
return baseUrl + url;
}
- /*
- * Is the host local? (i.e., not an outlink)
- *
- * This is a pretty flawed approach - assumes
- * a website only has one domain.
- *
- * TODO: I think we can blow this away for
- * Snowplow and handle the equivalent with a
- * whitelist of the site's domains.
- *
- */
- function isSiteHostName(hostName) {
- var i,
- alias,
- offset;
-
- for (i = 0; i < configHostsAlias.length; i++) {
-
- alias = helpers.fixupDomain(configHostsAlias[i].toLowerCase());
-
- if (hostName === alias) {
- return true;
- }
-
- if (alias.slice(0, 1) === '.') {
- if (hostName === alias.slice(1)) {
- return true;
- }
-
- offset = hostName.length - alias.length;
- if ((offset > 0) && (hostName.slice(offset) === alias)) {
- return true;
- }
- }
- }
- return false;
- }
-
/*
* Send request
*/
@@ -796,12 +743,14 @@
// TODO: rename to LinkClick
// TODO: this functionality is not yet fully implemented.
// See https://github.com/snowplow/snowplow/issues/75
- function logLink(url, linkType, context) {
- var sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', linkType);
- sb.add('t_url', purify(url));
- var request = getRequest(sb);
- sendRequest(request, configTrackerPause);
+ function logLink(linkId, linkClass, targetUrl, context) {
+ logUnstructEvent('link_click',{
+ link_id: linkId,
+ link_class: linkClass,
+ target_url: targetUrl
+ },
+ context)
+
}
/**
@@ -882,51 +831,16 @@
callback();
}
- /*
- * Construct regular expression of classes
- */
- function getClassesRegExp(configClasses, defaultClass) {
- var i,
- classesRegExp = '(^| )(piwik[_-]' + defaultClass;
-
- if (configClasses) {
- for (i = 0; i < configClasses.length; i++) {
- classesRegExp += '|' + configClasses[i];
- }
- }
- classesRegExp += ')( |$)';
-
- return new RegExp(classesRegExp);
- }
-
- /*
- * Link or Download?
- */
- // TODO: why is a download assumed to always be on the same host?
- // TODO: why return 0 if can't detect it as a link or download?
- function getLinkType(className, href, isInLink) {
- // outlinks
- if (!isInLink) {
- return 'lnk';
- }
-
- // does class indicate whether it is an (explicit/forced) outlink or a download?
- var downloadPattern = getClassesRegExp(configDownloadClasses, 'download'),
- linkPattern = getClassesRegExp(configLinkClasses, 'link'),
-
- // does file extension indicate that it is a download?
- downloadExtensionsPattern = new RegExp('\\.(' + configDownloadExtensions + ')([?]|$)', 'i');
-
- return linkPattern.test(className) ? 'lnk' : (downloadPattern.test(className) || downloadExtensionsPattern.test(href) ? 'dl' : 0);
- }
-
/*
* Process clicks
*/
function processClick(sourceElement) {
var parentElement,
tag,
- linkType;
+ linkId,
+ linkClass,
+ childElementId = sourceElement.id, // TODO: Do we need childElementId/-Class?
+ childElementClass = sourceElement.class;
while ((parentElement = sourceElement.parentNode) !== null &&
!lodash.isUndefined(parentElement) && // buggy IE5.5
@@ -943,13 +857,14 @@
// Ignore script pseudo-protocol links
if (!scriptProtocol.test(sourceHref)) {
- // Track outlinks and all downloads
- linkType = getLinkType(sourceElement.className, sourceHref, isSiteHostName(sourceHostName));
- if (linkType) {
- // decodeUrl %xx
- sourceHref = unescape(sourceHref);
- logLink(sourceHref, linkType);
- }
+
+ linkId = sourceElement.id;
+ linkClass = sourceElement.class;
+
+ // decodeUrl %xx
+ sourceHref = unescape(sourceHref);
+ logLink(linkId, linkClass, sourceHref);
+
}
}
}
@@ -1001,19 +916,38 @@
/*
* Add click handlers to anchor and AREA elements, except those to be ignored
*/
- function addClickListeners(enable) {
+ function addClickListeners(enable, excludedClasses) {
if (!linkTrackingInstalled) {
linkTrackingInstalled = true;
// iterate through anchor elements with href and AREA elements
var i,
- ignorePattern = getClassesRegExp(configIgnoreClasses, 'ignore'),
+ j,
+ excluded,
linkElements = documentAlias.links;
+ if (lodash.isUndefined(excludedClasses)) {
+ for (i = 0; i
Date: Tue, 4 Mar 2014 16:43:17 +0000
Subject: [PATCH 0035/1261] Began work on test suite for helpers.js
---
tests/helpers.js | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 tests/helpers.js
diff --git a/tests/helpers.js b/tests/helpers.js
new file mode 100644
index 000000000..1bdabb9ce
--- /dev/null
+++ b/tests/helpers.js
@@ -0,0 +1,67 @@
+/*
+ * JavaScript tracker for Snowplow: tests/helpers.js
+ *
+ * Significant portions copyright 2010 Anthon Pang. Remainder copyright
+ * 2012-2014 Snowplow Analytics Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Anthon Pang nor Snowplow Analytics Ltd nor the
+ * names of their contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+define([
+ 'intern!object',
+ 'intern/chai!assert',
+ 'intern/dojo/node!../src/js/lib/helpers'
+], function(registerSuite, assert, helpers) {
+
+ var url = 'http://www.example.com/path?lang=en&page=2#fragment';
+
+ registerSuite({
+
+ name: 'Helpers test',
+
+ 'Get host name from url': function() {
+ var value = helpers.getHostName(url);
+ assert.equal(value, 'www.example.com');
+ },
+
+ 'Fix up domain': function() {
+ var dom = '*.www.example.com.';
+ var fixedDom = helpers.fixUpDomain(dom);
+ assert.equal(fixedDom, '.www.example.com', 'Remove leading * and trailing . from domain name');
+ },
+
+ 'Get value from url': function() {
+ var value = helpers.fromQuerystring(page, url);
+ assert.equal(value, 2, 'Gets the value of a field-value pair')
+ },
+
+
+
+
+
+ })
From 35f8274471778f8430659e265ada84a6e69580ba Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 5 Mar 2014 09:05:04 +0000
Subject: [PATCH 0036/1261] Upgraded intern to 1.5.0 (#119)
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 5b92a8801..700a5fa73 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "1.0.3",
"devDependencies": {
"grunt": "~0.4.2",
- "intern": "~1.4.0",
+ "intern": "~1.5.0",
"semver": "~2.2.1",
"grunt-contrib-concat": "~0.3.0",
"grunt-yui-compressor": "git://github.com/fblundun/grunt-yui-compressor.git#feature/issue-8",
From 746d2d4d35cf03f0ee33f30f2720184020c2dd14 Mon Sep 17 00:00:00 2001
From: Alexander Dean
Date: Wed, 5 Mar 2014 18:52:48 +0000
Subject: [PATCH 0037/1261] Added Sauce Labs username and key
As per https://saucelabs.com/opensource/travis
/cc @fblundun - Fred I have separately invited you to a Sauce Labs sub-account (email inbound)...
---
.travis.yml | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 8d10e05b8..bc32e5a8c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,4 +4,8 @@ script: node node_modules/intern/runner.js config=tests/intern
language: node_js
before_script:
- npm install -g grunt-cli
-script: grunt travis
\ No newline at end of file
+script: grunt travis
+env:
+ global:
+ - secure: "Ort7jy0HpYi0EGfuRYGW4tawmVJzfUUNXhtJEOWR09FYL28XUyxvjUnpS1WZlD0/rBZiuDPBep1Tc81F88pSns4ZAg1lxlM/zheWrCKvYudeAia2g06OqOA1JfeVWX7TjemJ5s1lY66b5VQrDG1QLIO1RPjgWWea0MpSQzv00Ms="
+ - secure: "JFprkMXxrQZhRlYvJb+ZOr540QuzMU2jQtf39oPzg8uqcV5TDDWTuUZ6D3ogyNJnzH0mYDRzHZQEAqxkyjfndpIgN+a+dBM1l4WoKrTR9BpA3ZZD6zFEG7UrHBcvZgvopbY1wMPXbn4JL7J7SPPOjvvrjjIk/QIsTUYft/UOyXI="
From 44d12058c6eedcb9330454ad1a96e611692d6ac8 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 6 Mar 2014 12:30:11 +0000
Subject: [PATCH 0038/1261] enableLinkTracking now takes a context argument
---
src/js/tracker.js | 76 ++++++++++++++++++++++++-----------------------
1 file changed, 39 insertions(+), 37 deletions(-)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index fe73496cb..d6dc0aaf0 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -834,7 +834,7 @@
/*
* Process clicks
*/
- function processClick(sourceElement) {
+ function processClick(sourceElement, context) {
var parentElement,
tag,
linkId,
@@ -863,60 +863,62 @@
// decodeUrl %xx
sourceHref = unescape(sourceHref);
- logLink(linkId, linkClass, sourceHref);
+ logLink(linkId, linkClass, sourceHref, context);
}
}
}
/*
- * Handle click event
+ * Return function to handle click event
*/
- function clickHandler(evt) {
- var button,
- target;
-
- evt = evt || windowAlias.event;
- button = evt.which || evt.button;
- target = evt.target || evt.srcElement;
-
- // Using evt.type (added in IE4), we avoid defining separate handlers for mouseup and mousedown.
- if (evt.type === 'click') {
- if (target) {
- processClick(target);
- }
- } else if (evt.type === 'mousedown') {
- if ((button === 1 || button === 2) && target) {
- lastButton = button;
- lastTarget = target;
- } else {
+ function getClickHandler(context) {
+ return function(evt) {
+ var button,
+ target;
+
+ evt = evt || windowAlias.event;
+ button = evt.which || evt.button;
+ target = evt.target || evt.srcElement;
+
+ // Using evt.type (added in IE4), we avoid defining separate handlers for mouseup and mousedown.
+ if (evt.type === 'click') {
+ if (target) {
+ processClick(target, context);
+ }
+ } else if (evt.type === 'mousedown') {
+ if ((button === 1 || button === 2) && target) {
+ lastButton = button;
+ lastTarget = target;
+ } else {
+ lastButton = lastTarget = null;
+ }
+ } else if (evt.type === 'mouseup') {
+ if (button === lastButton && target === lastTarget) {
+ processClick(target, context);
+ }
lastButton = lastTarget = null;
}
- } else if (evt.type === 'mouseup') {
- if (button === lastButton && target === lastTarget) {
- processClick(target);
- }
- lastButton = lastTarget = null;
}
}
/*
* Add click listener to a DOM element
*/
- function addClickListener(element, enable) {
+ function addClickListener(element, enable, context) {
if (enable) {
// for simplicity and performance, we ignore drag events
- helpers.addEventListener(element, 'mouseup', clickHandler, false);
- helpers.addEventListener(element, 'mousedown', clickHandler, false);
+ helpers.addEventListener(element, 'mouseup', getClickHandler(context), false);
+ helpers.addEventListener(element, 'mousedown', getClickHandler(context), false);
} else {
- helpers.addEventListener(element, 'click', clickHandler, false);
+ helpers.addEventListener(element, 'click', getClickHandler(context), false);
}
}
/*
* Add click handlers to anchor and AREA elements, except those to be ignored
*/
- function addClickListeners(enable, excludedClasses) {
+ function addClickListeners(enable, excludedClasses, context) {
if (!linkTrackingInstalled) {
linkTrackingInstalled = true;
@@ -948,7 +950,7 @@
}
}
if (!excluded) {
- addClickListener(linkElements[i], enable);
+ addClickListener(linkElements[i], enable, context);
}
}
}
@@ -1139,8 +1141,8 @@
* @param DOMElement element
* @param bool enable If true, use pseudo click-handler (mousedown+mouseup)
*/
- addListener: function (element, enable) {
- addClickListener(element, enable);
+ addListener: function (element, enable, context) {
+ addClickListener(element, enable, context);
},
/**
@@ -1161,14 +1163,14 @@
* @param array excluded CSS classes to exclude from tracking
* @param bool enable If true, use pseudo click-handler (mousedown+mouseup)
*/
- enableLinkTracking: function (enable, excludedClasses) {
+ enableLinkTracking: function (enable, excludedClasses, context) {
if (mutSnowplowState.hasLoaded) {
// the load event has already fired, add the click listeners now
- addClickListeners(enable, excludedClasses);
+ addClickListeners(enable, excludedClasses, context);
} else {
// defer until page has loaded
mutSnowplowState.registeredOnLoadHandlers.push(function () {
- addClickListeners(enable, excludedClasses);
+ addClickListeners(enable, excludedClasses, context);
});
}
},
From 754c9b9896ef77f1eb059376dda5111c6dcece90 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 6 Mar 2014 15:00:22 +0000
Subject: [PATCH 0039/1261] Link tracking now captures element target. Renamed
enableLinkTracking -> enableLinkClickTracking, trackLink -> trackLinkClick.
---
src/js/tracker.js | 61 +++++++++++++++++++++++++----------------------
1 file changed, 33 insertions(+), 28 deletions(-)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index d6dc0aaf0..adf2d0b0b 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -736,17 +736,20 @@
/*
* Log the link or click with the server
*
- * @param string url The target URL
- * @param string linkType The type of link - link or download (see getLinkType() for details)
+ * @param string elementId
+ * @param string elementClass
+ * @param string elementTarget
+ * @param string targetUrl
* @param object context Custom context relating to the event
*/
// TODO: rename to LinkClick
// TODO: this functionality is not yet fully implemented.
// See https://github.com/snowplow/snowplow/issues/75
- function logLink(linkId, linkClass, targetUrl, context) {
+ function logLink(elementId, elementClass, elementTarget, targetUrl, context) {
logUnstructEvent('link_click',{
- link_id: linkId,
- link_class: linkClass,
+ element_id: elementId,
+ element_class: elementClass,
+ element_target: elementTarget,
target_url: targetUrl
},
context)
@@ -835,12 +838,12 @@
* Process clicks
*/
function processClick(sourceElement, context) {
+
var parentElement,
tag,
- linkId,
- linkClass,
- childElementId = sourceElement.id, // TODO: Do we need childElementId/-Class?
- childElementClass = sourceElement.class;
+ elementId,
+ elementClass,
+ elementTarget;
while ((parentElement = sourceElement.parentNode) !== null &&
!lodash.isUndefined(parentElement) && // buggy IE5.5
@@ -858,13 +861,13 @@
// Ignore script pseudo-protocol links
if (!scriptProtocol.test(sourceHref)) {
- linkId = sourceElement.id;
- linkClass = sourceElement.class;
+ elementId = sourceElement.id;
+ elementClass = sourceElement.className;
+ elementTarget = sourceElement.target;
// decodeUrl %xx
sourceHref = unescape(sourceHref);
- logLink(linkId, linkClass, sourceHref, context);
-
+ logLink(elementId, elementClass, elementTarget, sourceHref, context);
}
}
}
@@ -905,8 +908,8 @@
/*
* Add click listener to a DOM element
*/
- function addClickListener(element, enable, context) {
- if (enable) {
+ function addClickListener(element, pseudoClicks, context) {
+ if (pseudoClicks) {
// for simplicity and performance, we ignore drag events
helpers.addEventListener(element, 'mouseup', getClickHandler(context), false);
helpers.addEventListener(element, 'mousedown', getClickHandler(context), false);
@@ -918,7 +921,7 @@
/*
* Add click handlers to anchor and AREA elements, except those to be ignored
*/
- function addClickListeners(enable, excludedClasses, context) {
+ function addClickListeners(pseudoClicks, excludedClasses, context) {
if (!linkTrackingInstalled) {
linkTrackingInstalled = true;
@@ -950,7 +953,7 @@
}
}
if (!excluded) {
- addClickListener(linkElements[i], enable, context);
+ addClickListener(linkElements[i], pseudoClicks, context);
}
}
}
@@ -1141,8 +1144,8 @@
* @param DOMElement element
* @param bool enable If true, use pseudo click-handler (mousedown+mouseup)
*/
- addListener: function (element, enable, context) {
- addClickListener(element, enable, context);
+ addListener: function (element, pseudoClicks, context) {
+ addClickListener(element, pseudoClicks, context);
},
/**
@@ -1159,18 +1162,18 @@
* be "_self", "_top", or "_parent").
*
* @see https://bugs.webkit.org/show_bug.cgi?id=54783
- *
+ *
* @param array excluded CSS classes to exclude from tracking
- * @param bool enable If true, use pseudo click-handler (mousedown+mouseup)
+ * @param bool pseudoClicks If true, use pseudo click-handler (mousedown+mouseup)
*/
- enableLinkTracking: function (enable, excludedClasses, context) {
+ enableLinkClickTracking: function (excludedClasses, pseudoClicks, context) {
if (mutSnowplowState.hasLoaded) {
// the load event has already fired, add the click listeners now
- addClickListeners(enable, excludedClasses, context);
+ addClickListeners(pseudoClicks, excludedClasses, context);
} else {
// defer until page has loaded
mutSnowplowState.registeredOnLoadHandlers.push(function () {
- addClickListeners(enable, excludedClasses, context);
+ addClickListeners(pseudoClicks, excludedClasses, context);
});
}
},
@@ -1431,14 +1434,16 @@
/**
* Manually log a click from your own code
*
- * @param string sourceUrl
- * @param string linkType
+ * @param string elementId
+ * @param string elementClass
+ * @param string elementTarget
+ * @param string targetUrl
* @param object Custom context relating to the event
*/
// TODO: break this into trackLink(destUrl) and trackDownload(destUrl)
- trackLink: function(linkId, linkClass, targetUrl, context) {
+ trackLinkClick: function(elementId, elementClass, elementTarget, targetUrl, context) {
trackCallback(function () {
- logLink(linkId, linkClass, targetUrl, context);
+ logLink(elementId, elementClass, elementTarget, targetUrl, context);
});
},
From b9f5dcdf2add9435afca0675ffd860d6ac71ad10 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 6 Mar 2014 17:34:09 +0000
Subject: [PATCH 0040/1261] Element classes now in array format
---
CHANGELOG | 1 +
examples/web/async.html | 5 ++++-
src/js/tracker.js | 18 +++++++++---------
3 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 380cdfc8a..5e34f4629 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -22,6 +22,7 @@ Added initial localStorage support for intermittent offline beacons (#24)
Added new trackAdImpression, mapping to unstructured event (#13)
Removed references to referral cookie (#118)
Implement enableLinkTracking support (#51) (TODO)
+Replaced hard-coded version with template value (#120) (TODO)
Version 1.0.1 (2014-04-09)
--------------------------
diff --git a/examples/web/async.html b/examples/web/async.html
index 891cc2329..a6f410dc5 100644
--- a/examples/web/async.html
+++ b/examples/web/async.html
@@ -28,7 +28,7 @@
//window._snaq.push(['setUserIdFromCookie', '_sp_id.4209']) // Test this using Firefox because Chrome doesn't allow local cookies.
window._snaq.push(['setCustomUrl', '/overridden-url/']); // Override the page URL
window._snaq.push(['enableActivityTracking', 10, 10]); // Ping every 10 seconds after 10 seconds
- window._snaq.push(['enableLinkTracking']);
+ window._snaq.push(['enableLinkClickTracking', 'barred', true]);
window._snaq.push(['setPlatform', 'mob']);
window._snaq.push(['encodeBase64', false]); // Default is true
//window._snaq.push(['enableUserFingerprint', false]); // Turn off user fingerprinting
@@ -139,6 +139,9 @@ Asynchronous_examples_for_snowplow.js
Warning: if your browser's Do Not Track feature is enabled and respectDoNotTrack is not commented out, all tracking will be prevented.
+ Link
+ Ignored link
+