From 099dd3a63981aa3e6967e137c2d85325a739cb24 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 10:50:47 +0100
Subject: [PATCH 0001/1059] Stubbed CHANGELOG for 0.3.0
---
core/CHANGELOG | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/core/CHANGELOG b/core/CHANGELOG
index 5fbeb0805..ebfdeb600 100644
--- a/core/CHANGELOG
+++ b/core/CHANGELOG
@@ -1,3 +1,9 @@
+Version 0.3.0 (2014-xx-xx)
+--------------------------
+Apply callback to the Payload for an event rather than the event dictionary (#259) (TODO)
+Added page scroll parameters to trackPagePing (#257) (TODO)
+Added social tracking (#258) (TODO)
+
Version 0.2.0 (2014-08-07)
--------------------------
Added UUID to payload (#244)
From 70ad087075c9dcaf27ee19f1ee9cb67c52970c4c Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 10:51:16 +0100
Subject: [PATCH 0002/1059] Bumped version to 0.3.0
---
core/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/package.json b/core/package.json
index f1b33f577..cd663b675 100644
--- a/core/package.json
+++ b/core/package.json
@@ -1,6 +1,6 @@
{
"name": "snowplow-tracker-core",
- "version": "0.2.0",
+ "version": "0.3.0",
"devDependencies": {
"grunt": "^0.4.5",
"intern": "^2.0.1"
From 390943941f371acd5fc56d34171e89c80d722dbb Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 10:56:35 +0100
Subject: [PATCH 0003/1059] Apply callback to the Payload for an event rather
than the event dictionary (closes #259)
---
core/CHANGELOG | 2 +-
core/lib/core.js | 6 +++---
core/tests/core.js | 3 ++-
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/core/CHANGELOG b/core/CHANGELOG
index ebfdeb600..62b24e678 100644
--- a/core/CHANGELOG
+++ b/core/CHANGELOG
@@ -1,6 +1,6 @@
Version 0.3.0 (2014-xx-xx)
--------------------------
-Apply callback to the Payload for an event rather than the event dictionary (#259) (TODO)
+Apply callback to the Payload for an event rather than the event dictionary (#259)
Added page scroll parameters to trackPagePing (#257) (TODO)
Added social tracking (#258) (TODO)
diff --git a/core/lib/core.js b/core/lib/core.js
index 17a603a73..08540b4fb 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -82,6 +82,7 @@ function trackerCore(base64, callback) {
* @param sb object Payload
* @param array contexts Custom contexts relating to the event
* @param number tstamp Timestamp of the event
+ * @return object Payload after the callback is applied
*/
function track(sb, context, tstamp) {
sb.addDict(payloadPairs);
@@ -91,12 +92,11 @@ function trackerCore(base64, callback) {
sb.addJson('cx', 'co', completeContexts(context));
}
- var payload = sb.build();
if (typeof callback === 'function') {
- callback(payload);
+ callback(sb);
}
- return payload;
+ return sb;
}
/**
diff --git a/core/tests/core.js b/core/tests/core.js
index d7ac3e48d..ed511da18 100644
--- a/core/tests/core.js
+++ b/core/tests/core.js
@@ -24,6 +24,7 @@ define([
var tracker = core(false);
function compare(result, expected, message) {
+ result = result.build();
assert.ok(result['eid'], 'A UUID should be attached to all events');
delete result['eid'];
assert.ok(result['dtm'], 'A timestamp should be attached to all events');
@@ -310,7 +311,7 @@ define([
"Track a page view with a timestamp": function () {
var tstamp = 1000000000000;
- assert.strictEqual(tracker.trackPageView('http://www.example.com', null, null, null, tstamp)['dtm'], tstamp, 'A timestamp should be attached correctly');
+ assert.strictEqual(tracker.trackPageView('http://www.example.com', null, null, null, tstamp).build()['dtm'], tstamp, 'A timestamp should be attached correctly');
},
"Add individual name-value pairs to the payload": function () {
From 0ace84fa235fcf46266120306d686df93bd97517 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 10:57:35 +0100
Subject: [PATCH 0004/1059] Added page scroll parameters to trackPagePing
(fixes #257)
---
core/CHANGELOG | 2 +-
core/lib/core.js | 10 +++++++++-
core/tests/core.js | 8 ++++++--
3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/core/CHANGELOG b/core/CHANGELOG
index 62b24e678..b2bdaa954 100644
--- a/core/CHANGELOG
+++ b/core/CHANGELOG
@@ -1,7 +1,7 @@
Version 0.3.0 (2014-xx-xx)
--------------------------
Apply callback to the Payload for an event rather than the event dictionary (#259)
-Added page scroll parameters to trackPagePing (#257) (TODO)
+Added page scroll parameters to trackPagePing (#257)
Added social tracking (#258) (TODO)
Version 0.2.0 (2014-08-07)
diff --git a/core/lib/core.js b/core/lib/core.js
index 08540b4fb..7d440a684 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -280,16 +280,24 @@ function trackerCore(base64, callback) {
* by sending a page ping.
*
* @param string pageTitle The page title to attach to this page ping
+ * @param minxoffset Minimum page x offset seen in the last ping period
+ * @param maxXOffset Maximum page x offset seen in the last ping period
+ * @param minYOffset Minimum page y offset seen in the last ping period
+ * @param maxYOffset Maximum page y offset seen in the last ping period
* @param array context Custom contexts relating to the event
* @param number tstamp Timestamp of the event
* @return object Payload
*/
- trackPagePing: function (pageUrl, pageTitle, referrer, context, tstamp) {
+ trackPagePing: function (pageUrl, pageTitle, referrer, minXOffset, maxXOffset, minYOffset, maxYOffset, context, tstamp) {
var sb = payload.payloadBuilder(base64);
sb.add('e', 'pp'); // 'pv' for Page View
sb.add('url', pageUrl);
sb.add('page', pageTitle);
sb.add('refr', referrer);
+ sb.add('pp_mix', minXOffset);
+ sb.add('pp_max', maxXOffset);
+ sb.add('pp_miy', minYOffset);
+ sb.add('pp_may', maxYOffset);
return track(sb, context, tstamp);
},
diff --git a/core/tests/core.js b/core/tests/core.js
index ed511da18..30cae702e 100644
--- a/core/tests/core.js
+++ b/core/tests/core.js
@@ -51,10 +51,14 @@ define([
var expected = {
e: 'pp',
url: url,
- refr: referer
+ refr: referer,
+ pp_mix: 1,
+ pp_max: 2,
+ pp_miy: 3,
+ pp_may: 4
};
- compare(tracker.trackPagePing(url, null, referer), expected, 'A page ping should be tracked correctly');
+ compare(tracker.trackPagePing(url, null, referer, 1, 2, 3, 4), expected, 'A page ping should be tracked correctly');
},
"Track a structured event": function () {
From c58ba77c0c453e51b2784eee0ad096872fc765ef Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 11:11:36 +0100
Subject: [PATCH 0005/1059] Added trackSocialInteraction method
---
core/lib/core.js | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/core/lib/core.js b/core/lib/core.js
index 7d440a684..8d1812ce8 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -527,6 +527,31 @@ function trackerCore(base64, callback) {
})
};
+ return trackUnstructEvent(eventJson, context, tstamp);
+ },
+
+ /**
+ * Track a social event
+ *
+ * @param string action Social action performed
+ * @param string network Social network
+ * @param string target Object of the social action e.g. the video liked, the tweet retweeted
+ * @param string pagepath the URL of the page where the action occurred
+ * @param array Custom contexts relating to the event
+ * @param number tstamp Timestamp of the event
+ * @return object Payload
+ */
+ trackSocialInteraction: function (action, network, target, pagepath, context, tstamp) {
+ var eventJson = {
+ schema: 'iglu:com.snowplowanalytics.snowplow/social_interaction/jsonschema/1-0-0',
+ data: removeEmptyProperties({
+ action: action,
+ network: network,
+ target: target,
+ pagepath: pagepath
+ })
+ };
+
return trackUnstructEvent(eventJson, context, tstamp);
}
};
From 3f2e753775cd03dbffc07421e26068c0d4edca90 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 12:40:10 +0100
Subject: [PATCH 0006/1059] Added test for trackSocialInteraction (closes #258)
---
core/CHANGELOG | 5 +++--
core/tests/core.js | 27 +++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/core/CHANGELOG b/core/CHANGELOG
index b2bdaa954..b77f6ce29 100644
--- a/core/CHANGELOG
+++ b/core/CHANGELOG
@@ -1,8 +1,9 @@
Version 0.3.0 (2014-xx-xx)
--------------------------
-Apply callback to the Payload for an event rather than the event dictionary (#259)
+Applied callback to the Payload for an event rather than the event dictionary (#259)
Added page scroll parameters to trackPagePing (#257)
-Added social tracking (#258) (TODO)
+Added social tracking (#258)
+Add addTo- and removeFrom- basket methods (#260) (TODO)
Version 0.2.0 (2014-08-07)
--------------------------
diff --git a/core/tests/core.js b/core/tests/core.js
index 30cae702e..d86f6ec4c 100644
--- a/core/tests/core.js
+++ b/core/tests/core.js
@@ -290,6 +290,33 @@ define([
compare(tracker.trackAdConversion(conversionId, costModel, cost, category, action, property, initialValue, advertiserId, campaignId), expected, 'An ad conversion should be tracked correctly');
},
+ "Track a social interaction": function () {
+ var action = 'like';
+ var network = 'facebook';
+ var target = 'status-0000345345';
+ var pagepath = 'http://www.mypage.com';
+
+ var inputJson = {
+ schema: 'iglu:com.snowplowanalytics.snowplow/social_interaction/jsonschema/1-0-0',
+ data: {
+ action: action,
+ network: network,
+ target: target,
+ pagepath: pagepath
+ }
+ };
+
+ var expected = {
+ e: 'ue',
+ ue_pr: JSON.stringify({
+ schema: unstructEventSchema,
+ data: inputJson
+ })
+ };
+
+ compare(tracker.trackSocialInteraction(action, network, target, pagepath), expected);
+ },
+
"Track a page view with custom context": function () {
var url = 'http://www.example.com';
var page = 'title page';
From 1a4b8d151914229fa034d53af1a17fe03cce325e Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 15:20:49 +0100
Subject: [PATCH 0007/1059] Added trackAddToCart and trackRemoveFromCart
methods (closes #260)
---
core/CHANGELOG | 2 +-
core/lib/core.js | 54 +++++++++++++++++++++++++++++++++++++++
core/tests/core.js | 63 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/core/CHANGELOG b/core/CHANGELOG
index b77f6ce29..ea4e0aa21 100644
--- a/core/CHANGELOG
+++ b/core/CHANGELOG
@@ -3,7 +3,7 @@ Version 0.3.0 (2014-xx-xx)
Applied callback to the Payload for an event rather than the event dictionary (#259)
Added page scroll parameters to trackPagePing (#257)
Added social tracking (#258)
-Add addTo- and removeFrom- basket methods (#260) (TODO)
+Added trackAddToCart and trackRemoveFromCart methods (#260)
Version 0.2.0 (2014-08-07)
--------------------------
diff --git a/core/lib/core.js b/core/lib/core.js
index 8d1812ce8..65aef0d45 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -553,6 +553,60 @@ function trackerCore(base64, callback) {
};
return trackUnstructEvent(eventJson, context, tstamp);
+ },
+
+ /**
+ * Track an add-to-cart event
+ *
+ * @param string sku Required. Item's SKU code.
+ * @param string name Optional. Product name.
+ * @param string category Optional. Product category.
+ * @param string price Required. Product price.
+ * @param string quantity Required. Quantity added.
+ * @param string currency Optional. Product price currency.
+ * @param array context Optional. Context relating to the event.
+ * @param number tstamp Optional. Timestamp of the event
+ * @return object Payload
+ */
+ trackAddToCart: function (sku, name, category, price, quantity, currency, context, tstamp) {
+ return trackUnstructEvent({
+ schema: 'iglu:com.snowplowanalytics.snowplow/add_to_cart/jsonschema/1-0-0',
+ data: removeEmptyProperties({
+ ti_sku: sku,
+ ti_name: name,
+ ti_category: category,
+ ti_price: price,
+ ti_quantity: quantity,
+ ti_currency: currency
+ })
+ }, context, tstamp);
+ },
+
+ /**
+ * Track a remove-from-cart event
+ *
+ * @param string sku Required. Item's SKU code.
+ * @param string name Optional. Product name.
+ * @param string category Optional. Product category.
+ * @param string price Required. Product price.
+ * @param string quantity Required. Quantity removed.
+ * @param string currency Optional. Product price currency.
+ * @param array context Optional. Context relating to the event.
+ * @param number tstamp Optional. Timestamp of the event
+ * @return object Payload
+ */
+ trackRemoveFromCart: function (sku, name, category, price, quantity, currency, context, tstamp) {
+ return trackUnstructEvent({
+ schema: 'iglu:com.snowplowanalytics.snowplow/remove_from_cart/jsonschema/1-0-0',
+ data: removeEmptyProperties({
+ ti_sku: sku,
+ ti_name: name,
+ ti_category: category,
+ ti_price: price,
+ ti_quantity: quantity,
+ ti_currency: currency
+ })
+ }, context, tstamp);
}
};
}
diff --git a/core/tests/core.js b/core/tests/core.js
index d86f6ec4c..6060fd473 100644
--- a/core/tests/core.js
+++ b/core/tests/core.js
@@ -317,6 +317,69 @@ define([
compare(tracker.trackSocialInteraction(action, network, target, pagepath), expected);
},
+
+ "Track an add-to-cart event": function () {
+ var sku = '4q345';
+ var price = 17;
+ var quantity = 2;
+ var name = 'red shoes';
+ var category = 'clothing';
+ var currency = 'USD';
+
+ var inputJson = {
+ schema: 'iglu:com.snowplowanalytics.snowplow/add_to_cart/jsonschema/1-0-0',
+ data: {
+ ti_sku: sku,
+ ti_name: name,
+ ti_category: category,
+ ti_price: price,
+ ti_quantity: quantity,
+ ti_currency: currency
+ }
+ };
+
+ var expected = {
+ e: 'ue',
+ ue_pr: JSON.stringify({
+ schema: unstructEventSchema,
+ data: inputJson
+ })
+ };
+
+ compare(tracker.trackAddToCart(sku, name, category, price, quantity, currency), expected);
+ },
+
+ "Track a remove-from-cart event": function () {
+ var sku = '4q345';
+ var price = 17;
+ var quantity = 2;
+ var name = 'red shoes';
+ var category = 'clothing';
+ var currency = 'USD';
+
+ var inputJson = {
+ schema: 'iglu:com.snowplowanalytics.snowplow/remove_from_cart/jsonschema/1-0-0',
+ data: {
+ ti_sku: sku,
+ ti_name: name,
+ ti_category: category,
+ ti_price: price,
+ ti_quantity: quantity,
+ ti_currency: currency
+ }
+ };
+
+ var expected = {
+ e: 'ue',
+ ue_pr: JSON.stringify({
+ schema: unstructEventSchema,
+ data: inputJson
+ })
+ };
+
+ compare(tracker.trackRemoveFromCart(sku, name, category, price, quantity, currency), expected);
+ },
+
"Track a page view with custom context": function () {
var url = 'http://www.example.com';
var page = 'title page';
From 390d7d3d93091df49c84a6284010ddc03646fc57 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 16:29:46 +0100
Subject: [PATCH 0008/1059] Improved CodeClimate rating
---
core/lib/core.js | 10 +++++-----
core/lib/payload.js | 14 +++++++-------
core/tests/payload.js | 2 +-
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/core/lib/core.js b/core/lib/core.js
index 65aef0d45..bc51a84af 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -161,7 +161,7 @@ function trackerCore(base64, callback) {
* @param string version
*/
setTrackerVersion: function (version) {
- addPayloadPair('tv', version)
+ addPayloadPair('tv', version);
},
/**
@@ -179,7 +179,7 @@ function trackerCore(base64, callback) {
* @param string appId
*/
setAppId: function (appId) {
- addPayloadPair('aid', appId)
+ addPayloadPair('aid', appId);
},
/**
@@ -253,7 +253,7 @@ function trackerCore(base64, callback) {
* @param string appId
*/
setIpAddress: function (ip) {
- addPayloadPair('ip', ip)
+ addPayloadPair('ip', ip);
},
trackUnstructEvent: trackUnstructEvent,
@@ -290,7 +290,7 @@ function trackerCore(base64, callback) {
*/
trackPagePing: function (pageUrl, pageTitle, referrer, minXOffset, maxXOffset, minYOffset, maxYOffset, context, tstamp) {
var sb = payload.payloadBuilder(base64);
- sb.add('e', 'pp'); // 'pv' for Page View
+ sb.add('e', 'pp'); // 'pp' for Page Ping
sb.add('url', pageUrl);
sb.add('page', pageTitle);
sb.add('refr', referrer);
@@ -372,7 +372,7 @@ function trackerCore(base64, callback) {
* @return object Payload
*/
trackEcommerceTransactionItem: function (orderId, sku, name, category, price, quantity, currency, context, tstamp) {
- var sb = payload.payloadBuilder(base64)
+ var sb = payload.payloadBuilder(base64);
sb.add("e", "ti"); // 'tr' for Transaction Item
sb.add("ti_id", orderId);
sb.add("ti_sk", sku);
diff --git a/core/lib/payload.js b/core/lib/payload.js
index 78d93c176..7f1b1fc17 100644
--- a/core/lib/payload.js
+++ b/core/lib/payload.js
@@ -27,12 +27,12 @@
* See: http://tools.ietf.org/html/rfc4648#page-7
*/
function base64urlencode(data) {
- if (!data) return data;
+ if (!data) {
+ return data;
+ }
var enc = base64.base64encode(data);
- return enc.replace(/=/g, '')
- .replace(/\+/g, '-')
- .replace(/\//g, '_');
+ return enc.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
}
/*
@@ -73,7 +73,7 @@
var add = function (key, value) {
if (value !== undefined && value !== null && value !== '') {
- dict[key] = value
+ dict[key] = value;
}
};
@@ -83,7 +83,7 @@
add(key, dict[key]);
}
}
- }
+ };
var addJson = function (keyIfEncoded, keyIfNotEncoded, json) {
@@ -105,6 +105,6 @@
return dict;
}
};
- }
+ };
}());
diff --git a/core/tests/payload.js b/core/tests/payload.js
index 86092275c..6939299b6 100644
--- a/core/tests/payload.js
+++ b/core/tests/payload.js
@@ -99,7 +99,7 @@ define([
sb.addDict({
'e': 'pv',
'tv': 'js-2.0.0'
- })
+ });
assert.deepEqual(sb.build(), {e: 'pv', tv: 'js-2.0.0'}, 'A dictionary of name-value pairs should be added to the payload');
},
From 1bbeab4ee700a73a6c45acd88f85a7a34f9244bd Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 1 Oct 2014 14:14:22 +0100
Subject: [PATCH 0009/1059] Added trackFormChange and trackFormSubmission
methods
---
core/CHANGELOG | 1 +
core/lib/core.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/core/CHANGELOG b/core/CHANGELOG
index ea4e0aa21..250042dac 100644
--- a/core/CHANGELOG
+++ b/core/CHANGELOG
@@ -4,6 +4,7 @@ Applied callback to the Payload for an event rather than the event dictionary (#
Added page scroll parameters to trackPagePing (#257)
Added social tracking (#258)
Added trackAddToCart and trackRemoveFromCart methods (#260)
+Added trackFormChange and trackFormSubmission methods (#261)
Version 0.2.0 (2014-08-07)
--------------------------
diff --git a/core/lib/core.js b/core/lib/core.js
index bc51a84af..bc240e9b6 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -47,12 +47,14 @@ function trackerCore(base64, callback) {
* Returns a copy of a JSON with undefined and null properties removed
*
* @param object eventJson JSON to clean
+ * @param object exemptFields Set of fields which should not be removed even if empty
* @return object A cleaned copy of eventJson
*/
- function removeEmptyProperties(eventJson) {
+ function removeEmptyProperties(eventJson, exemptFields) {
var ret = {};
+ exemptFields = exemptFields || {};
for (var k in eventJson) {
- if (eventJson[k] !== null && typeof eventJson[k] !== 'undefined') {
+ if (exemptFields[k] || (eventJson[k] !== null && typeof eventJson[k] !== 'undefined')) {
ret[k] = eventJson[k];
}
}
@@ -607,6 +609,50 @@ function trackerCore(base64, callback) {
ti_currency: currency
})
}, context, tstamp);
+ },
+
+ /**
+ * @param string formId The parent form ID
+ * @param string elementId ID of the changed element
+ * @param string nodeName "INPUT", "TEXTAREA", or "SELECT"
+ * @param string type Type of the changed element if its type is "INPUT"
+ * @param array elementClasses List of classes of the changed element
+ * @param string value The new value of the changed element
+ * @param array context Optional. Context relating to the event.
+ * @param number tstamp Optional. Timestamp of the event
+ * @return object Payload
+ */
+ trackFormChange: function(formId, elementId, nodeName, type, elementClasses, value, context, tstamp) {
+ return trackUnstructEvent({
+ schema: 'iglu:com.snowplowanalytics.snowplow/change_form/jsonschema/1-0-0',
+ data: removeEmptyProperties({
+ formId: formId,
+ elementId: elementId,
+ nodeName: nodeName,
+ type: type,
+ elementClasses: elementClasses,
+ value: value
+ }, {'value': true})
+ }, context, tstamp);
+ },
+
+ /**
+ * @param string formId ID of the form
+ * @param array formClasses Classes of the form
+ * @param array elements Mutable elements within the form
+ * @param array context Optional. Context relating to the event.
+ * @param number tstamp Optional. Timestamp of the event
+ * @return object Payload
+ */
+ trackFormSubmission: function(formId, formClasses, elements, context, tstamp) {
+ return trackUnstructEvent({
+ schema: 'iglu:com.snowplowanalytics.snowplow/submit_form/jsonschema/1-0-0',
+ data: removeEmptyProperties({
+ formId: formId,
+ formClasses: formClasses,
+ elements: elements
+ })
+ }, context, tstamp);
}
};
}
From 0347bbe4401df55c7d011788b47cddf2c1ad1b31 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 2 Oct 2014 09:39:00 +0100
Subject: [PATCH 0010/1059] Added content field to trackLinkClick (closes #262)
---
core/CHANGELOG | 1 +
core/lib/core.js | 12 +++++++++---
core/tests/core.js | 6 ++++--
3 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/core/CHANGELOG b/core/CHANGELOG
index 250042dac..e3e5b2d91 100644
--- a/core/CHANGELOG
+++ b/core/CHANGELOG
@@ -5,6 +5,7 @@ Added page scroll parameters to trackPagePing (#257)
Added social tracking (#258)
Added trackAddToCart and trackRemoveFromCart methods (#260)
Added trackFormChange and trackFormSubmission methods (#261)
+Added content field to trackLinkClick (#262)
Version 0.2.0 (2014-08-07)
--------------------------
diff --git a/core/lib/core.js b/core/lib/core.js
index bc240e9b6..c05e08e36 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -408,22 +408,24 @@ function trackerCore(base64, callback) {
/**
* Log the link or click with the server
*
+ * @param string targetUrl
* @param string elementId
* @param array elementClasses
* @param string elementTarget
- * @param string targetUrl
+ * @param string elementContent innerHTML of the link
* @param array context Custom contexts relating to the event
* @param number tstamp Timestamp of the event
* @return object Payload
*/
- trackLinkClick: function (targetUrl, elementId, elementClasses, elementTarget, context, tstamp) {
+ trackLinkClick: function (targetUrl, elementId, elementClasses, elementTarget, elementContent, context, tstamp) {
var eventJson = {
schema: 'iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-0',
data: removeEmptyProperties({
targetUrl: targetUrl,
elementId: elementId,
elementClasses: elementClasses,
- elementTarget: elementTarget
+ elementTarget: elementTarget,
+ elementContent: elementContent
}),
};
@@ -612,6 +614,8 @@ function trackerCore(base64, callback) {
},
/**
+ * Track the value of a form field changing
+ *
* @param string formId The parent form ID
* @param string elementId ID of the changed element
* @param string nodeName "INPUT", "TEXTAREA", or "SELECT"
@@ -637,6 +641,8 @@ function trackerCore(base64, callback) {
},
/**
+ * Track a form submission event
+ *
* @param string formId ID of the form
* @param array formClasses Classes of the form
* @param array elements Mutable elements within the form
diff --git a/core/tests/core.js b/core/tests/core.js
index 6060fd473..c3fdbcbac 100644
--- a/core/tests/core.js
+++ b/core/tests/core.js
@@ -142,13 +142,15 @@ define([
var targetUrl = 'http://www.example.com';
var elementId = 'first header';
var elementClasses = ['header'];
+ var elementContent = 'link';
var inputJson = {
schema: 'iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-0',
data: {
targetUrl: targetUrl,
elementId: elementId,
- elementClasses: elementClasses
+ elementClasses: elementClasses,
+ elementContent: elementContent
}
};
var expected = {
@@ -159,7 +161,7 @@ define([
})
};
- compare(tracker.trackLinkClick(targetUrl, elementId, elementClasses), expected, 'A link click should be tracked correctly');
+ compare(tracker.trackLinkClick(targetUrl, elementId, elementClasses, null, elementContent), expected, 'A link click should be tracked correctly');
},
"Track a screen view": function () {
From 3fb74d93639474e4a08223f0f9097e79ed4b9310 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 2 Oct 2014 10:35:24 +0100
Subject: [PATCH 0011/1059] Added trackSiteSearch method (closes #263)
---
core/CHANGELOG | 1 +
core/lib/core.js | 23 +++++++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/core/CHANGELOG b/core/CHANGELOG
index e3e5b2d91..2f895656d 100644
--- a/core/CHANGELOG
+++ b/core/CHANGELOG
@@ -5,6 +5,7 @@ Added page scroll parameters to trackPagePing (#257)
Added social tracking (#258)
Added trackAddToCart and trackRemoveFromCart methods (#260)
Added trackFormChange and trackFormSubmission methods (#261)
+Added trackSiteSearch method (#263)
Added content field to trackLinkClick (#262)
Version 0.2.0 (2014-08-07)
diff --git a/core/lib/core.js b/core/lib/core.js
index c05e08e36..2185f4e30 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -659,6 +659,29 @@ function trackerCore(base64, callback) {
elements: elements
})
}, context, tstamp);
+ },
+
+ /**
+ * Track an internal search event
+ *
+ * @param array terms Search terms
+ * @param array filters Search filters
+ * @param totalResults Number of results
+ * @param pageResults Number of results displayed on page
+ * @param array context Optional. Context relating to the event.
+ * @param number tstamp Optional. Timestamp of the event
+ * @return object Payload
+ */
+ trackSiteSearch: function(terms, filters, totalResults, pageResults, context, tstamp) {
+ return trackUnstructEvent({
+ schema: 'iglu:com.snowplowanalytics.snowplow/site_search/jsonschema/1-0-0',
+ data: removeEmptyProperties({
+ terms: terms,
+ filters: filters,
+ totalResults: totalResults,
+ pageResults: pageResults
+ })
+ }, context, tstamp);
}
};
}
From 455e87e9f822cfb84e214dd2e06be4d877bdc2b5 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 2 Oct 2014 11:00:34 +0100
Subject: [PATCH 0012/1059] Added tests for new methods
---
core/lib/core.js | 2 +-
core/tests/core.js | 90 +++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 90 insertions(+), 2 deletions(-)
diff --git a/core/lib/core.js b/core/lib/core.js
index 2185f4e30..3cc796ef6 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -419,7 +419,7 @@ function trackerCore(base64, callback) {
*/
trackLinkClick: function (targetUrl, elementId, elementClasses, elementTarget, elementContent, context, tstamp) {
var eventJson = {
- schema: 'iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-0',
+ schema: 'iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-1',
data: removeEmptyProperties({
targetUrl: targetUrl,
elementId: elementId,
diff --git a/core/tests/core.js b/core/tests/core.js
index c3fdbcbac..4bb0e14b6 100644
--- a/core/tests/core.js
+++ b/core/tests/core.js
@@ -145,7 +145,7 @@ define([
var elementContent = 'link';
var inputJson = {
- schema: 'iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-0',
+ schema: 'iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-1',
data: {
targetUrl: targetUrl,
elementId: elementId,
@@ -382,6 +382,94 @@ define([
compare(tracker.trackRemoveFromCart(sku, name, category, price, quantity, currency), expected);
},
+ "Track a form change event": function () {
+ var formId = "parent";
+ var elementId = "child";
+ var nodeName = "INPUT";
+ var type = "text";
+ var elementClasses = ["important"];
+ var value = "male";
+
+ var inputJson = {
+ schema: 'iglu:com.snowplowanalytics.snowplow/change_form/jsonschema/1-0-0',
+ data: {
+ formId: formId,
+ elementId: elementId,
+ nodeName: nodeName,
+ type: type,
+ elementClasses: elementClasses,
+ value: value
+ }
+ };
+
+ var expected = {
+ e: 'ue',
+ ue_pr: JSON.stringify({
+ schema: unstructEventSchema,
+ data: inputJson
+ })
+ };
+
+ compare(tracker.trackFormChange(formId, elementId, nodeName, type, elementClasses, value), expected);
+ },
+
+ "Track a form submission event": function () {
+ var formId = "parent";
+ var formClasses = ["formclass"];
+ var elements = [{
+ name: "gender",
+ value: "male",
+ nodeName: "INPUT",
+ type: "text"
+ }];
+
+ var inputJson = {
+ schema: 'iglu:com.snowplowanalytics.snowplow/submit_form/jsonschema/1-0-0',
+ data: {
+ formId: formId,
+ formClasses: formClasses,
+ elements: elements
+ }
+ };
+
+ var expected = {
+ e: 'ue',
+ ue_pr: JSON.stringify({
+ schema: unstructEventSchema,
+ data: inputJson
+ })
+ };
+
+ compare(tracker.trackFormSubmission(formId, formClasses, elements), expected);
+ },
+
+ "Track a site seach event": function () {
+ var terms = ["javascript", "development"];
+ var filters = ["books"];
+ var totalResults = 35;
+ var pageResults = 10;
+
+ var inputJson = {
+ schema: 'iglu:com.snowplowanalytics.snowplow/site_search/jsonschema/1-0-0',
+ data: {
+ terms: terms,
+ filters: filters,
+ totalResults: totalResults,
+ pageResults: pageResults
+ }
+ };
+
+ var expected = {
+ e: 'ue',
+ ue_pr: JSON.stringify({
+ schema: unstructEventSchema,
+ data: inputJson
+ })
+ };
+
+ compare(tracker.trackSiteSearch(terms, filters, totalResults, pageResults), expected);
+ },
+
"Track a page view with custom context": function () {
var url = 'http://www.example.com';
var page = 'title page';
From 231d7423cdcd1107f1033898e9f3fc8836c77dcd Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 7 Oct 2014 14:19:40 +0100
Subject: [PATCH 0013/1059] Removed pagepath argument from
trackSocialInteraction
---
core/lib/core.js | 6 ++----
core/tests/core.js | 6 ++----
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/core/lib/core.js b/core/lib/core.js
index 3cc796ef6..472ab6517 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -540,19 +540,17 @@ function trackerCore(base64, callback) {
* @param string action Social action performed
* @param string network Social network
* @param string target Object of the social action e.g. the video liked, the tweet retweeted
- * @param string pagepath the URL of the page where the action occurred
* @param array Custom contexts relating to the event
* @param number tstamp Timestamp of the event
* @return object Payload
*/
- trackSocialInteraction: function (action, network, target, pagepath, context, tstamp) {
+ trackSocialInteraction: function (action, network, target, context, tstamp) {
var eventJson = {
schema: 'iglu:com.snowplowanalytics.snowplow/social_interaction/jsonschema/1-0-0',
data: removeEmptyProperties({
action: action,
network: network,
- target: target,
- pagepath: pagepath
+ target: target
})
};
diff --git a/core/tests/core.js b/core/tests/core.js
index 4bb0e14b6..c473599eb 100644
--- a/core/tests/core.js
+++ b/core/tests/core.js
@@ -296,15 +296,13 @@ define([
var action = 'like';
var network = 'facebook';
var target = 'status-0000345345';
- var pagepath = 'http://www.mypage.com';
var inputJson = {
schema: 'iglu:com.snowplowanalytics.snowplow/social_interaction/jsonschema/1-0-0',
data: {
action: action,
network: network,
- target: target,
- pagepath: pagepath
+ target: target
}
};
@@ -316,7 +314,7 @@ define([
})
};
- compare(tracker.trackSocialInteraction(action, network, target, pagepath), expected);
+ compare(tracker.trackSocialInteraction(action, network, target), expected);
},
From 44fa7de1c93d4c934e6b6b36a7d6d889cf8c4401 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 7 Oct 2014 14:20:50 +0100
Subject: [PATCH 0014/1059] Removed ti_ prefix from fields of trackAddToBasket
and trackRemoveFromBasket
---
core/lib/core.js | 24 ++++++++++++------------
core/tests/core.js | 24 ++++++++++++------------
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/core/lib/core.js b/core/lib/core.js
index 472ab6517..52f711f6c 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -574,12 +574,12 @@ function trackerCore(base64, callback) {
return trackUnstructEvent({
schema: 'iglu:com.snowplowanalytics.snowplow/add_to_cart/jsonschema/1-0-0',
data: removeEmptyProperties({
- ti_sku: sku,
- ti_name: name,
- ti_category: category,
- ti_price: price,
- ti_quantity: quantity,
- ti_currency: currency
+ sku: sku,
+ name: name,
+ category: category,
+ price: price,
+ quantity: quantity,
+ currency: currency
})
}, context, tstamp);
},
@@ -601,12 +601,12 @@ function trackerCore(base64, callback) {
return trackUnstructEvent({
schema: 'iglu:com.snowplowanalytics.snowplow/remove_from_cart/jsonschema/1-0-0',
data: removeEmptyProperties({
- ti_sku: sku,
- ti_name: name,
- ti_category: category,
- ti_price: price,
- ti_quantity: quantity,
- ti_currency: currency
+ sku: sku,
+ name: name,
+ category: category,
+ price: price,
+ quantity: quantity,
+ currency: currency
})
}, context, tstamp);
},
diff --git a/core/tests/core.js b/core/tests/core.js
index c473599eb..6746c71d5 100644
--- a/core/tests/core.js
+++ b/core/tests/core.js
@@ -329,12 +329,12 @@ define([
var inputJson = {
schema: 'iglu:com.snowplowanalytics.snowplow/add_to_cart/jsonschema/1-0-0',
data: {
- ti_sku: sku,
- ti_name: name,
- ti_category: category,
- ti_price: price,
- ti_quantity: quantity,
- ti_currency: currency
+ sku: sku,
+ name: name,
+ category: category,
+ price: price,
+ quantity: quantity,
+ currency: currency
}
};
@@ -360,12 +360,12 @@ define([
var inputJson = {
schema: 'iglu:com.snowplowanalytics.snowplow/remove_from_cart/jsonschema/1-0-0',
data: {
- ti_sku: sku,
- ti_name: name,
- ti_category: category,
- ti_price: price,
- ti_quantity: quantity,
- ti_currency: currency
+ sku: sku,
+ name: name,
+ category: category,
+ price: price,
+ quantity: quantity,
+ currency: currency
}
};
From 5640a6c6ea0814d5aa59d93e036a33b01815701c Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 8 Oct 2014 12:39:48 +0100
Subject: [PATCH 0015/1059] Added missing semicolons to core files
---
core/lib/core.js | 2 +-
core/tests/payload.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/core/lib/core.js b/core/lib/core.js
index 52f711f6c..0972ebe3f 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -682,6 +682,6 @@ function trackerCore(base64, callback) {
}, context, tstamp);
}
};
-}
+};
module.exports = trackerCore;
diff --git a/core/tests/payload.js b/core/tests/payload.js
index 6939299b6..746a52ba2 100644
--- a/core/tests/payload.js
+++ b/core/tests/payload.js
@@ -69,7 +69,7 @@ define([
'Identify an empty JSON': function () {
var emptyJson = {};
- assert.strictEqual(payload.isNonEmptyJson(emptyJson), false, '{} should be identified as empty')
+ assert.strictEqual(payload.isNonEmptyJson(emptyJson), false, '{} should be identified as empty');
},
'Build a payload': function () {
From bc6d9775728813f5c2a6576b1be827baa77a7184 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 8 Oct 2014 17:07:41 +0100
Subject: [PATCH 0016/1059] Changed site_search filter field type to object
Renamed add_to_cart/remove_from_cart price field to unitPrice
---
core/lib/core.js | 14 +++++++-------
core/tests/core.js | 17 ++++++++++-------
2 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/core/lib/core.js b/core/lib/core.js
index 0972ebe3f..0c2c13b37 100644
--- a/core/lib/core.js
+++ b/core/lib/core.js
@@ -563,21 +563,21 @@ function trackerCore(base64, callback) {
* @param string sku Required. Item's SKU code.
* @param string name Optional. Product name.
* @param string category Optional. Product category.
- * @param string price Required. Product price.
+ * @param string unitPrice Optional. Product price.
* @param string quantity Required. Quantity added.
* @param string currency Optional. Product price currency.
* @param array context Optional. Context relating to the event.
* @param number tstamp Optional. Timestamp of the event
* @return object Payload
*/
- trackAddToCart: function (sku, name, category, price, quantity, currency, context, tstamp) {
+ trackAddToCart: function (sku, name, category, unitPrice, quantity, currency, context, tstamp) {
return trackUnstructEvent({
schema: 'iglu:com.snowplowanalytics.snowplow/add_to_cart/jsonschema/1-0-0',
data: removeEmptyProperties({
sku: sku,
name: name,
category: category,
- price: price,
+ unitPrice: unitPrice,
quantity: quantity,
currency: currency
})
@@ -590,21 +590,21 @@ function trackerCore(base64, callback) {
* @param string sku Required. Item's SKU code.
* @param string name Optional. Product name.
* @param string category Optional. Product category.
- * @param string price Required. Product price.
+ * @param string unitPrice Optional. Product price.
* @param string quantity Required. Quantity removed.
* @param string currency Optional. Product price currency.
* @param array context Optional. Context relating to the event.
* @param number tstamp Optional. Timestamp of the event
* @return object Payload
*/
- trackRemoveFromCart: function (sku, name, category, price, quantity, currency, context, tstamp) {
+ trackRemoveFromCart: function (sku, name, category, unitPrice, quantity, currency, context, tstamp) {
return trackUnstructEvent({
schema: 'iglu:com.snowplowanalytics.snowplow/remove_from_cart/jsonschema/1-0-0',
data: removeEmptyProperties({
sku: sku,
name: name,
category: category,
- price: price,
+ unitPrice: unitPrice,
quantity: quantity,
currency: currency
})
@@ -663,7 +663,7 @@ function trackerCore(base64, callback) {
* Track an internal search event
*
* @param array terms Search terms
- * @param array filters Search filters
+ * @param object filters Search filters
* @param totalResults Number of results
* @param pageResults Number of results displayed on page
* @param array context Optional. Context relating to the event.
diff --git a/core/tests/core.js b/core/tests/core.js
index 6746c71d5..718f7d725 100644
--- a/core/tests/core.js
+++ b/core/tests/core.js
@@ -320,7 +320,7 @@ define([
"Track an add-to-cart event": function () {
var sku = '4q345';
- var price = 17;
+ var unitPrice = 17;
var quantity = 2;
var name = 'red shoes';
var category = 'clothing';
@@ -332,7 +332,7 @@ define([
sku: sku,
name: name,
category: category,
- price: price,
+ unitPrice: unitPrice,
quantity: quantity,
currency: currency
}
@@ -346,12 +346,12 @@ define([
})
};
- compare(tracker.trackAddToCart(sku, name, category, price, quantity, currency), expected);
+ compare(tracker.trackAddToCart(sku, name, category, unitPrice, quantity, currency), expected);
},
"Track a remove-from-cart event": function () {
var sku = '4q345';
- var price = 17;
+ var unitPrice = 17;
var quantity = 2;
var name = 'red shoes';
var category = 'clothing';
@@ -363,7 +363,7 @@ define([
sku: sku,
name: name,
category: category,
- price: price,
+ unitPrice: unitPrice,
quantity: quantity,
currency: currency
}
@@ -377,7 +377,7 @@ define([
})
};
- compare(tracker.trackRemoveFromCart(sku, name, category, price, quantity, currency), expected);
+ compare(tracker.trackRemoveFromCart(sku, name, category, unitPrice, quantity, currency), expected);
},
"Track a form change event": function () {
@@ -443,7 +443,10 @@ define([
"Track a site seach event": function () {
var terms = ["javascript", "development"];
- var filters = ["books"];
+ var filters = {
+ "safeSearch": true,
+ "category": "books"
+ };
var totalResults = 35;
var pageResults = 10;
From 72ffaee31b2bc207ca240adab62d4a030022a009 Mon Sep 17 00:00:00 2001
From: Alex Dean
Date: Tue, 4 Nov 2014 00:06:20 +0000
Subject: [PATCH 0017/1059] Finalized CHANGELOG for core
---
core/CHANGELOG | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/CHANGELOG b/core/CHANGELOG
index 2f895656d..0532c2f92 100644
--- a/core/CHANGELOG
+++ b/core/CHANGELOG
@@ -1,4 +1,4 @@
-Version 0.3.0 (2014-xx-xx)
+Version 0.3.0 (2014-11-03)
--------------------------
Applied callback to the Payload for an event rather than the event dictionary (#259)
Added page scroll parameters to trackPagePing (#257)
From cb89e04e6ae6a6aeaefd1733c2f2af201b05cb3f Mon Sep 17 00:00:00 2001
From: Alex Dean
Date: Tue, 4 Nov 2014 08:31:33 +0000
Subject: [PATCH 0018/1059] Bumped date to today
---
core/CHANGELOG | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/CHANGELOG b/core/CHANGELOG
index 0532c2f92..d80e5bb33 100644
--- a/core/CHANGELOG
+++ b/core/CHANGELOG
@@ -1,4 +1,4 @@
-Version 0.3.0 (2014-11-03)
+Version 0.3.0 (2014-11-04)
--------------------------
Applied callback to the Payload for an event rather than the event dictionary (#259)
Added page scroll parameters to trackPagePing (#257)
From 59297cafcda2f9d983946cc49a11530f17f1238c Mon Sep 17 00:00:00 2001
From: Kurt Johnson
Date: Wed, 27 Aug 2014 11:12:47 +1000
Subject: [PATCH 0019/1059] amended the code so the argmap looks for a
forceSecureTracker boolean property which if it exists and is set to true
will force the tracker to run over https
---
src/js/tracker.js | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 783dc961a..d50691d0d 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -75,7 +75,6 @@
/************************************************************
* Private members
************************************************************/
-
var
// Aliases
documentAlias = document,
@@ -166,6 +165,10 @@
// Document character set
documentCharset = documentAlias.characterSet || documentAlias.charset,
+ // This forces the tracker to be HTTPS even if the page is not secure
+ forceSecureTracker = argmap.hasOwnProperty('forceSecureTracker') ? (argmap.forceSecureTracker === true) : false,
+
+
// Browser language (or Windows language for IE). Imperfect but CloudFront doesn't log the Accept-Language header
browserLanguage = navigatorAlias.userLanguage || navigatorAlias.language,
@@ -570,7 +573,10 @@
* @return string collectorUrl The tracker URL with protocol
*/
function asCollectorUrl(rawUrl) {
- return ('https:' == documentAlias.location.protocol ? 'https' : 'http') + '://' + rawUrl + '/i';
+ if(forceSecureTracker)
+ return ('https' + '://' + rawUrl + '/i');
+ else
+ return ('https:' == documentAlias.location.protocol ? 'https' : 'http') + '://' + rawUrl + '/i';
}
/**
From 297c7a0ab193f1d5942aeffa465c3e9c15fffa8f Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 25 Sep 2014 09:09:33 +0100
Subject: [PATCH 0020/1059] Stubbed CHANGELOG for 2.1.0
---
CHANGELOG | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 63854b48f..5b616490d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,29 @@
+Version 2.1.0 (2014-xx-xx)
+--------------------------
+Added automated form submission tracking (#252) (TODO)
+Stopped outbound queue from triggering multiple times per event (#251) (TODO)
+Changed default configCookiePath to "/" (#250) (TODO)
+Added RUM / web performance context using HTML5 Web Performance API (#248) (TODO)
+Added ability to execute a custom callback once sp.js is loaded (#246) (TODO)
+Added internal site search event (#241) (TODO)
+Improved document height detection (#236) (TODO)
+Fixed SauceLabs red status (#235) (TODO)
+Added tests for base64 encoding weird characters (#234) (TODO)
+Fixed CloudFront cache invalidation (#230) (TODO)
+Renamed /dist to /deploy (#216) (TODO)
+Moved context querystring to end of JS-generated beacons (#204) (TODO)
+Added pageUnloadGuard to wait until outbound queue is empty before unloading (#202) (TODO)
+Added event_id generation (#190) (TODO)
+Added content field to link click events (#187) (TODO)
+Removed dependency on fblundun fork of grunt-yui-compressor (#172) (TODO)
+Replaced "Getting started" with Vagrant-using "Contributing quickstart" (#169) (TODO)
+Added async-large.html (#162) (TODO)
+Improved F rating for tracker.js in CodeClimate (#150) (TODO)
+Clarified scope of localStorage (#122) (TODO)
+Added addTo- and removeFrom- Basket events (#97) (TODO)
+Added further Intern unit tests (#76) (TODO)
+Added social tracking features (#12) (TODO)
+
Version 2.0.2 (2014-10-20)
--------------------------
Changed default configCookiePath to "/" (#250)
From 0a4928538ec823f0362f0d644e61161c64531831 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 25 Sep 2014 09:10:40 +0100
Subject: [PATCH 0021/1059] Bumped version to 2.1.0
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 285021c58..3b333a105 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "snowplow-tracker",
- "version": "2.0.2",
+ "version": "2.1.0",
"devDependencies": {
"grunt": "~0.4.2",
"intern": "~1.5.0",
From dfc1014640eadff4bffb3b0ed45c67b812bd40d4 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 25 Sep 2014 09:12:59 +0100
Subject: [PATCH 0022/1059] Changed default configCookiePath to "/" (fixes
#250)
---
CHANGELOG | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5b616490d..90f1cab65 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,7 +2,7 @@ Version 2.1.0 (2014-xx-xx)
--------------------------
Added automated form submission tracking (#252) (TODO)
Stopped outbound queue from triggering multiple times per event (#251) (TODO)
-Changed default configCookiePath to "/" (#250) (TODO)
+Changed default configCookiePath to "/" (#250)
Added RUM / web performance context using HTML5 Web Performance API (#248) (TODO)
Added ability to execute a custom callback once sp.js is loaded (#246) (TODO)
Added internal site search event (#241) (TODO)
From 44c2d0872f9677b3b38703af3c5c29480af162c2 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 25 Sep 2014 09:30:29 +0100
Subject: [PATCH 0023/1059] Added ability to execute a custom callback once
sp.js is loaded (closes #246)
---
CHANGELOG | 2 +-
src/js/in_queue.js | 13 ++++++++++---
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 90f1cab65..c639b81d8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,7 +4,7 @@ Added automated form submission tracking (#252) (TODO)
Stopped outbound queue from triggering multiple times per event (#251) (TODO)
Changed default configCookiePath to "/" (#250)
Added RUM / web performance context using HTML5 Web Performance API (#248) (TODO)
-Added ability to execute a custom callback once sp.js is loaded (#246) (TODO)
+Added ability to execute a custom callback once sp.js is loaded (#246)
Added internal site search event (#241) (TODO)
Improved document height detection (#236) (TODO)
Fixed SauceLabs red status (#235) (TODO)
diff --git a/src/js/in_queue.js b/src/js/in_queue.js
index 115fce6c5..84a6bb3ee 100644
--- a/src/js/in_queue.js
+++ b/src/js/in_queue.js
@@ -141,15 +141,22 @@
* [ functionObject, optional_parameters ]
*/
function applyAsyncFunction() {
- var i, f, parameterArray, inputString, parsedString, names, namedTrackers;
+ var i, f, parameterArray, input, parsedString, names, namedTrackers;
// Outer loop in case someone push'es in zarg of arrays
for (i = 0; i < arguments.length; i += 1) {
parameterArray = arguments[i];
// Arguments is not an array, so we turn it into one
- inputString = Array.prototype.shift.call(parameterArray);
- parsedString = parseInputString(inputString);
+ input = Array.prototype.shift.call(parameterArray);
+
+ // Custom callback rather than tracker method
+ if (lodash.isFunction(input)) {
+ input.apply(this, parameterArray);
+ continue;
+ }
+
+ parsedString = parseInputString(input);
f = parsedString[0];
names = parsedString[1];
From f78c8f18cf08851214e40eae715246b6b8b10584 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 25 Sep 2014 09:34:00 +0100
Subject: [PATCH 0024/1059] Added unit test for custom onload callbacks (#76)
(#246)
---
tests/nonfunctional/in_queue.js | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/tests/nonfunctional/in_queue.js b/tests/nonfunctional/in_queue.js
index ed96ea567..bd8bae81a 100644
--- a/tests/nonfunctional/in_queue.js
+++ b/tests/nonfunctional/in_queue.js
@@ -106,5 +106,11 @@ define([
asyncQueue.push(["logConfigWriteCookies:sp"]);
assert.strictEqual(writeCookies, false, "The second tracker has not been assigned a unique cookie namespace, so cannot create cookies");
},
+
+ "Execute a user-defined custom callback": function () {
+ var callbackExecuted = false;
+ asyncQueue.push([function () { callbackExecuted = true; }]);
+ assert.isTrue(callbackExecuted);
+ }
});
});
From 46e820ff816fdf63f5b0fdc72bc146a66b0eac6b Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 25 Sep 2014 09:39:57 +0100
Subject: [PATCH 0025/1059] Renamed /dist to /deploy (closes #216)
---
CHANGELOG | 2 +-
Gruntfile.js | 24 ++++++++++++------------
{dist => deploy}/.gitignore | 0
3 files changed, 13 insertions(+), 13 deletions(-)
rename {dist => deploy}/.gitignore (100%)
diff --git a/CHANGELOG b/CHANGELOG
index c639b81d8..82fd7c15c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,7 +10,7 @@ Improved document height detection (#236) (TODO)
Fixed SauceLabs red status (#235) (TODO)
Added tests for base64 encoding weird characters (#234) (TODO)
Fixed CloudFront cache invalidation (#230) (TODO)
-Renamed /dist to /deploy (#216) (TODO)
+Renamed /dist to /deploy (#216)
Moved context querystring to end of JS-generated beacons (#204) (TODO)
Added pageUnloadGuard to wait until outbound queue is empty before unloading (#202) (TODO)
Added event_id generation (#190) (TODO)
diff --git a/Gruntfile.js b/Gruntfile.js
index 05dcab8fe..b014349ae 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -91,7 +91,7 @@ module.exports = function(grunt) {
browserify: {
main: {
files: {
- 'dist/bundle.js': ['src/js/init.js']
+ 'deploy/bundle.js': ['src/js/init.js']
}
},
test: {
@@ -103,14 +103,14 @@ module.exports = function(grunt) {
},
concat: {
- dist: {
+ deploy: {
options: {
'report': 'gzip',
'banner': '<%= banner %>',
'process': true
},
- src: ['dist/bundle.js'],
- dest: 'dist/snowplow.js'
+ src: ['deploy/bundle.js'],
+ dest: 'deploy/snowplow.js'
},
tag: {
options: {
@@ -122,15 +122,15 @@ module.exports = function(grunt) {
},
min: {
- dist: {
+ deploy: {
options: {
linebreak: 1000,
report: 'gzip'
},
files: [
{
- src: 'dist/snowplow.js',
- dest: 'dist/sp.js'
+ src: 'deploy/snowplow.js',
+ dest: 'deploy/sp.js'
}
]
},
@@ -198,7 +198,7 @@ module.exports = function(grunt) {
},
upload: [
{
- src: 'dist/sp.js',
+ src: 'deploy/sp.js',
dest: '<%= pkg.version %>/sp.js'
}
]
@@ -211,7 +211,7 @@ module.exports = function(grunt) {
},
upload: [
{
- src: 'dist/sp.js',
+ src: 'deploy/sp.js',
dest: '<%= pkg.pinnedVersion %>/sp.js'
}
]
@@ -243,9 +243,9 @@ module.exports = function(grunt) {
});
});
- grunt.registerTask('default', 'Build lodash, Browserify, add banner, and minify', ['lodash', 'browserify:main', 'concat:dist', 'min:dist']);
- grunt.registerTask('publish', 'Upload to S3 and invalidate Cloudfront (full semantic version only)', ['upload_setup', 'lodash', 'browserify:main', 'concat:dist', 'min:dist', '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:main', 'concat:dist', 'min:dist', 's3', 'invalidate_cloudfront']);
+ grunt.registerTask('default', 'Build lodash, Browserify, add banner, and minify', ['lodash', 'browserify:main', 'concat:deploy', 'min:deploy']);
+ grunt.registerTask('publish', 'Upload to S3 and invalidate Cloudfront (full semantic version only)', ['upload_setup', 'lodash', 'browserify:main', 'concat:deploy', 'min:deploy', '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:main', 'concat:deploy', 'min:deploy', 's3', 'invalidate_cloudfront']);
grunt.registerTask('test', 'Intern tests', ['browserify:test', 'intern']);
grunt.registerTask('travis', 'Intern tests for Travis CI', ['lodash','browserify:test','intern']);
grunt.registerTask('tags', 'Minifiy the Snowplow invocation tag', ['min:tag', 'concat:tag']);
diff --git a/dist/.gitignore b/deploy/.gitignore
similarity index 100%
rename from dist/.gitignore
rename to deploy/.gitignore
From ab411c4fa0ef44b3068f740f5d9500e498441c8d Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 25 Sep 2014 11:17:51 +0100
Subject: [PATCH 0026/1059] Improved efficiency of enableLinkClickTracking
(fixes #254)
---
CHANGELOG | 1 +
src/js/tracker.js | 27 +++++++++++++++------------
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 82fd7c15c..3b8eed3f4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -23,6 +23,7 @@ Clarified scope of localStorage (#122) (TODO)
Added addTo- and removeFrom- Basket events (#97) (TODO)
Added further Intern unit tests (#76) (TODO)
Added social tracking features (#12) (TODO)
+Improved efficiency of enableLinkClickTracking (#254)
Version 2.0.2 (2014-10-20)
--------------------------
diff --git a/src/js/tracker.js b/src/js/tracker.js
index d50691d0d..d0a2283a7 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -977,19 +977,14 @@
}
/*
- * Check whether a list of classes contains any of the classes of a link element
+ * Check whether a set of classes contains any of the classes of a link element
* Used to determine whether clicks on that link should be tracked
*/
function checkLink(linkElement, specifiedClasses) {
- var linkClasses = lodash.map(linkElement.classList),
- i,
- j;
-
- for (i = 0; i < linkClasses.length; i++) {
- for (j = 0; j < specifiedClasses.length; j++) {
- if (linkClasses[i] === specifiedClasses[j]) {
- return true;
- }
+ var linkClasses = lodash.map(linkElement.classList);
+ for (var i=0; i
Date: Fri, 26 Sep 2014 14:20:52 +0100
Subject: [PATCH 0027/1059] Removed deprecated trackImpression method (fixes
#256)
---
CHANGELOG | 2 ++
src/js/tracker.js | 41 -----------------------------------------
2 files changed, 2 insertions(+), 41 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3b8eed3f4..3933a5281 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -24,6 +24,8 @@ Added addTo- and removeFrom- Basket events (#97) (TODO)
Added further Intern unit tests (#76) (TODO)
Added social tracking features (#12) (TODO)
Improved efficiency of enableLinkClickTracking (#254)
+Integrated the Tracker Core (#255) (TODO)
+Removed deprecated trackImpression method (#256)
Version 2.0.2 (2014-10-20)
--------------------------
diff --git a/src/js/tracker.js b/src/js/tracker.js
index d0a2283a7..afb912772 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -797,31 +797,6 @@
logUnstructEvent(eventJson, context);
}
- /**
- * Log an ad impression
- *
- * @param string bannerId Identifier for the ad banner displayed
- * @param string campaignId (optional) Identifier for the campaign which the banner belongs to
- * @param string advertiserId (optional) Identifier for the advertiser which the campaign belongs to
- * @param string userId (optional) Ad server identifier for the viewer of the banner
- * @param object context Custom context relating to the event
- */
- // TODO: rename to logAdImpression and deprecate logImpression
- // TODO: should add impressionId as well.
- // TODO: should add in zoneId (aka placementId, slotId?) as well
- // TODO: change ad_ to ai_?
- function logImpression(bannerId, campaignId, advertiserId, userId, context) {
- var sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', 'ad'); // 'ad' for AD impression
- sb.add('ad_ba', bannerId);
- sb.add('ad_ca', campaignId)
- sb.add('ad_ad', advertiserId);
- sb.add('ad_uid', userId);
- sb.addJson('cx', 'co', completeContext(context));
- var request = getRequest(sb);
- sendRequest(request, configTrackerPause);
- }
-
/*
* Browser prefix
*/
@@ -1529,22 +1504,6 @@
});
},
- /**
- * Track an ad being served
- *
- * DEPRECATED: Use trackAdImpression()
- *
- * @param string bannerId Identifier for the ad banner displayed
- * @param string campaignId (optional) Identifier for the campaign which the banner belongs to
- * @param string advertiserId (optional) Identifier for the advertiser which the campaign belongs to
- * @param string userId (optional) Ad server identifier for the viewer of the banner
- * @param object Custom context relating to the event
- */
- trackImpression: function (bannerId, campaignId, advertiserId, userId, context) {
- helpers.warn('trackImpression is deprecated. When version 1.1.0 is released, switch to trackAdImpression.');
- logImpression(bannerId, campaignId, advertiserId, userId, context);
- },
-
/**
* Track an ad being served
*
From c8735b939cd7b3482ba9dd3686e473d40c22fd0b Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Fri, 26 Sep 2014 15:29:59 +0100
Subject: [PATCH 0028/1059] Integrated the Tracker Core (closes #255) This adds
event_id generation (closes #190)
---
CHANGELOG | 5 +-
package.json | 3 +-
src/js/lib/helpers.js | 14 --
src/js/tracker.js | 339 +++++++++++-------------------------------
4 files changed, 91 insertions(+), 270 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3933a5281..62775aca4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,12 +8,11 @@ Added ability to execute a custom callback once sp.js is loaded (#246)
Added internal site search event (#241) (TODO)
Improved document height detection (#236) (TODO)
Fixed SauceLabs red status (#235) (TODO)
-Added tests for base64 encoding weird characters (#234) (TODO)
Fixed CloudFront cache invalidation (#230) (TODO)
Renamed /dist to /deploy (#216)
Moved context querystring to end of JS-generated beacons (#204) (TODO)
Added pageUnloadGuard to wait until outbound queue is empty before unloading (#202) (TODO)
-Added event_id generation (#190) (TODO)
+Added event_id generation (#190)
Added content field to link click events (#187) (TODO)
Removed dependency on fblundun fork of grunt-yui-compressor (#172) (TODO)
Replaced "Getting started" with Vagrant-using "Contributing quickstart" (#169) (TODO)
@@ -24,7 +23,7 @@ Added addTo- and removeFrom- Basket events (#97) (TODO)
Added further Intern unit tests (#76) (TODO)
Added social tracking features (#12) (TODO)
Improved efficiency of enableLinkClickTracking (#254)
-Integrated the Tracker Core (#255) (TODO)
+Integrated the Tracker Core (#255)
Removed deprecated trackImpression method (#256)
Version 2.0.2 (2014-10-20)
diff --git a/package.json b/package.json
index 3b333a105..683856f3f 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,8 @@
"JSON": "~1.0.0",
"sha1": "git://github.com/pvorb/node-sha1.git#v1.0.0",
"grunt-lodash": "~0.3.0",
- "browser-cookie-lite": "~0.3.1"
+ "browser-cookie-lite": "~0.3.1",
+ "snowplow-tracker-core": "0.3.0"
},
"contributors": [
"Alex Dean",
diff --git a/src/js/lib/helpers.js b/src/js/lib/helpers.js
index 414f20195..b8533aa5b 100644
--- a/src/js/lib/helpers.js
+++ b/src/js/lib/helpers.js
@@ -138,20 +138,6 @@
return decodeURIComponent(match[1].replace(/\+/g, ' '));
}
- /*
- * Remove from an object every property whose value is
- * null, undefined, an empty string, or an empty array
- */
- object.deleteEmptyProperties = function (collection) {
- for (var i in collection) {
- if (collection.hasOwnProperty(i) && (lodash.isUndefined(collection[i]) ||
- lodash.isNull(collection[i]) || collection[i].length === 0)) {
- delete collection[i];
- }
- }
- return collection;
- }
-
/*
* Only log deprecation warnings if they won't cause an error
*/
diff --git a/src/js/tracker.js b/src/js/tracker.js
index afb912772..b233e4e15 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -44,6 +44,7 @@
json2 = require('JSON'),
sha1 = require('sha1'),
requestQueue = require('./out_queue'),
+ coreConstructor = require('snowplow-tracker-core'),
object = typeof exports !== 'undefined' ? exports : this; // For eventual node.js environment support
@@ -76,6 +77,12 @@
* Private members
************************************************************/
var
+ // Tracker core
+ core = coreConstructor(true, function(payload) {
+ addBrowserData(payload);
+ sendRequest(payload);
+ }),
+
// Aliases
documentAlias = document,
windowAlias = window,
@@ -156,9 +163,6 @@
// Life of the session cookie (in seconds)
configSessionCookieTimeout = 1800, // 30 minutes
- // Enable Base64 encoding for unstructured events
- configEncodeBase64 = argmap.hasOwnProperty('encodeBase64') ? argmap.encodeBase64 : true,
-
// Default hash seed for MurmurHash3 in detectors.detectSignature
configUserFingerprintHashSeed = argmap.hasOwnProperty('userFingerprintSeed') ? argmap.userFingerprintSeed : 123412414,
@@ -227,15 +231,26 @@
outQueueManager = new requestQueue.OutQueueManager(functionName, namespace);
- /*
- * Creates a JSON from the default header and a custom contexts array
- */
- function completeContext(context) {
- if (!lodash.isEmpty(context)) {
- return {
- schema: configContextSchema,
- data: context
- };
+ // Enable base 64 encoding for unstructured events and custom contexts
+ core.setBase64Encoding(argmap.hasOwnProperty('encodeBase64') ? argmap.encodeBase64 : true);
+
+ // Set up unchanging name-value pairs
+ core.setTrackerVersion(version);
+ core.setTrackerNamespace(namespace);
+ core.setAppId(configTrackerSiteId);
+ core.setPlatform(configPlatform);
+ core.setTimezone(detectors.detectTimezone());
+ core.addPayloadPair('lang', browserLanguage);
+ core.addPayloadPair('cs', documentCharset);
+
+ // Browser features. Cookies, color depth and resolution don't get prepended with f_ (because they're not optional features)
+ for (var i in browserFeatures) {
+ if (Object.prototype.hasOwnProperty.call(browserFeatures, i)) {
+ if (i === 'res' || i === 'cd' || i === 'cookie') {
+ core.addPayloadPair(i, browserFeatures[i]);
+ } else {
+ core.addPayloadPair('f_', browserFeatures[i]);
+ }
}
}
@@ -301,6 +316,25 @@
return baseUrl + url;
}
+ /*
+ * Convert a dictionary to a querystring
+ */
+ function getQuerystring(request) {
+ var querystring = '?',
+ firstPair = true;
+ for (var key in request) {
+ if (request.hasOwnProperty(key)) {
+ if (!firstPair) {
+ querystring += '&';
+ } else {
+ firstPair = false;
+ }
+ querystring += encodeURIComponent(key) + '=' + encodeURIComponent(request[key]);
+ }
+ }
+ return querystring;
+ }
+
/*
* Send request
*/
@@ -308,7 +342,7 @@
var now = new Date();
if (!configDoNotTrack) {
- outQueueManager.enqueueRequest(request, configCollectorUrl);
+ outQueueManager.enqueueRequest(getQuerystring(request.build()), configCollectorUrl);
mutSnowplowState.expireDateTime = now.getTime() + delay;
}
}
@@ -450,60 +484,31 @@
}
/*
- * Get the current timestamp:
- * milliseconds since epoch.
- */
- function getTimestamp() {
- var now = new Date(),
- nowTs = now.getTime();
-
- return nowTs;
- }
-
- /*
- * Attaches all the common web fields to the request
+ * Attaches common web fields to every request
* (resolution, url, referrer, etc.)
* Also sets the required cookies.
- *
- * Takes in a string builder, adds in parameters to it
- * and then generates the request.
*/
- function getRequest(sb) {
- var i,
- now = new Date(),
- nowTs = Math.round(now.getTime() / 1000),
- newVisitor,
- _domainUserId, // Don't shadow the global
- visitCount,
- createTs,
- currentVisitTs,
- lastVisitTs,
- referralTs,
- referralUrl,
- referralUrlMaxLength = 1024,
- currentReferrerHostName,
- originalReferrerHostName,
- idname = getSnowplowCookieName('id'),
+ function addBrowserData(sb) {
+ var nowTs = Math.round(new Date().getTime() / 1000),
sesname = getSnowplowCookieName('ses'),
- id = loadDomainUserIdCookie(),
ses = getSnowplowCookieValue('ses'), // aka cookie.cookie(sesname)
- currentUrl = configCustomUrl || locationHrefAlias,
- featurePrefix;
+ id = loadDomainUserIdCookie(),
+ newVisitor = id[0],
+ _domainUserId = id[1], // We could use the global (domainUserId) but this is better etiquette
+ createTs = id[2],
+ visitCount = id[3],
+ currentVisitTs = id[4],
+ lastVisitTs = id[5],
+ featurePrefix,
+ i;
if (configDoNotTrack && configWriteCookies) {
cookie.cookie(idname, '', -1, configCookiePath, configCookieDomain);
cookie.cookie(sesname, '', -1, configCookiePath, configCookieDomain);
- return '';
+ return;
}
- newVisitor = id[0];
- _domainUserId = id[1]; // We could use the global (domainUserId) but this is better etiquette
- createTs = id[2];
- visitCount = id[3];
- currentVisitTs = id[4];
- lastVisitTs = id[5];
-
- // New session
+ // New session?
if (!ses) {
// New session (aka new visit)
visitCount++;
@@ -511,46 +516,28 @@
lastVisitTs = currentVisitTs;
}
- // Build out the rest of the request - first add fields we can safely skip encoding
- sb.addRaw('dtm', getTimestamp());
- sb.addRaw('tid', String(Math.random()).slice(2, 8));
- sb.addRaw('vp', detectors.detectViewport());
- sb.addRaw('ds', detectors.detectDocumentSize());
- sb.addRaw('vid', visitCount);
- sb.addRaw('duid', _domainUserId); // Set to our local variable
-
- // Encode all these
- sb.add('p', configPlatform);
- sb.add('tv', version);
+ // Build out the rest of the request
+ sb.add('vp', detectors.detectViewport());
+ sb.add('ds', detectors.detectDocumentSize());
+ sb.add('vid', visitCount);
+ sb.add('duid', _domainUserId); // Set to our local variable
sb.add('fp', userFingerprint);
- sb.add('aid', configTrackerSiteId);
- sb.add('lang', browserLanguage);
- sb.add('cs', documentCharset);
- sb.add('tz', timezone);
- sb.add('uid', businessUserId); // Business-defined user ID
- sb.add('tna', namespace);
+ sb.add('uid', businessUserId);
// Adds with custom conditions
- if (configReferrerUrl.length) sb.add('refr', purify(configReferrerUrl));
-
- // Browser features. Cookies, color depth and resolution don't get prepended with f_ (because they're not optional features)
- for (i in browserFeatures) {
- if (Object.prototype.hasOwnProperty.call(browserFeatures, i)) {
- featurePrefix = (i === 'res' || i === 'cd' || i === 'cookie') ? '' : 'f_';
- sb.addRaw(featurePrefix + i, browserFeatures[i]);
- }
+ if (configReferrerUrl.length) {
+ sb.add('refr', purify(configReferrerUrl));
}
// Add the page URL last as it may take us over the IE limit (and we don't always need it)
- sb.add('url', purify(currentUrl));
- var request = sb.build();
+ sb.add('url', purify(configCustomUrl || locationHrefAlias));
+
// Update cookies
if (configWriteCookies) {
setDomainUserIdCookie(_domainUserId, createTs, visitCount, nowTs, lastVisitTs);
cookie.cookie(sesname, '*', configSessionCookieTimeout, configCookiePath, configCookieDomain);
}
- return request;
}
/**
@@ -591,12 +578,7 @@
var pageTitle = helpers.fixupTitle(customTitle || configTitle);
// Log page view
- var sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', 'pv'); // 'pv' for Page View
- sb.add('page', pageTitle);
- sb.addJson('cx', 'co', completeContext(context));
- var request = getRequest(sb);
- sendRequest(request, configTrackerPause);
+ core.trackPageView(purify(configCustomUrl || locationHrefAlias), pageTitle, purify(configReferrerUrl), context);
// Send ping (to log that user has stayed on page)
var now = new Date();
@@ -649,40 +631,9 @@
* @param object context Custom context relating to the event
*/
function logPagePing(pageTitle, context) {
- var sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', 'pp'); // 'pp' for Page Ping
- sb.add('page', pageTitle);
- sb.addRaw('pp_mix', minXOffset); // Global
- sb.addRaw('pp_max', maxXOffset); // Global
- sb.addRaw('pp_miy', minYOffset); // Global
- sb.addRaw('pp_may', maxYOffset); // Global
- sb.addJson('cx', 'co', completeContext(context));
resetMaxScrolls();
- var request = getRequest(sb);
- sendRequest(request, configTrackerPause);
- }
-
- /**
- * Log a structured event happening on this page
- *
- * @param string category The name you supply for the group of objects you want to track
- * @param string action A string that is uniquely paired with each category, and commonly used to define the type of user interaction for the web object
- * @param string label (optional) An optional string to provide additional dimensions to the event data
- * @param string property (optional) Describes the object or the action performed on it, e.g. quantity of item added to basket
- * @param numeric value (optional) An integer or floating point number to provide numerical data about the user event
- * @param object context Custom context relating to the event
- */
- function logStructEvent(category, action, label, property, value, context) {
- var sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', 'se'); // 'se' for Structured Event
- sb.add('se_ca', category);
- sb.add('se_ac', action)
- sb.add('se_la', label);
- sb.add('se_pr', property);
- sb.add('se_va', value);
- sb.addJson('cx', 'co', completeContext(context));
- var request = getRequest(sb);
- sendRequest(request, configTrackerPause);
+ core.trackPagePing(purify(configCustomUrl || locationHrefAlias), pageTitle, purify(configReferrerUrl),
+ minXOffset, maxXOffset, minYOffset, maxYOffset, context);
}
/**
@@ -692,19 +643,7 @@
* @param object context Custom context relating to the event
*/
function logUnstructEvent(eventJson, context) {
- helpers.deleteEmptyProperties(eventJson.data);
- if (!lodash.isEmpty(eventJson.data)) {
- var envelope = {
- schema: configUnstructEventSchema,
- data: eventJson
- },
- sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', 'ue'); // 'ue' for Unstructured Event
- sb.addJson('ue_px', 'ue_pr', envelope);
- sb.addJson('cx', 'co', completeContext(context));
- var request = getRequest(sb);
- sendRequest(request, configTrackerPause);
- }
+ core.trackUnstructEvent(eventJson, context);
}
/**
@@ -721,22 +660,8 @@
* @param string currency The currency the total/tax/shipping are expressed in
* @param object context Custom context relating to the event
*/
- // TODO: add params to comment
function logTransaction(orderId, affiliation, total, tax, shipping, city, state, country, currency, context) {
- var sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', 'tr'); // 'tr' for TRansaction
- sb.add('tr_id', orderId);
- sb.add('tr_af', affiliation);
- sb.add('tr_tt', total);
- sb.add('tr_tx', tax);
- sb.add('tr_sh', shipping);
- sb.add('tr_ci', city);
- sb.add('tr_st', state);
- sb.add('tr_co', country);
- sb.add('tr_cu', currency);
- sb.addJson('cx', 'co', completeContext(context));
- var request = getRequest(sb);
- sendRequest(request, configTrackerPause);
+ core.trackEcommerceTransaction(orderId, affiliation, total, tax, shipping, city, state, country, currency, context);
}
/**
@@ -751,50 +676,8 @@
* @param string currency The currency the price is expressed in
* @param object context Custom context relating to the event
*/
- // TODO: add params to comment
function logTransactionItem(orderId, sku, name, category, price, quantity, currency, context) {
- var sb = payload.payloadBuilder(configEncodeBase64);
- sb.add('e', 'ti'); // 'ti' for Transaction Item
- sb.add('ti_id', orderId);
- sb.add('ti_sk', sku);
- sb.add('ti_na', name);
- sb.add('ti_ca', category);
- sb.add('ti_pr', price);
- sb.add('ti_qu', quantity);
- sb.add('ti_cu', currency);
- sb.addJson('cx', 'co', completeContext(context));
- var request = getRequest(sb);
- sendRequest(request, configTrackerPause);
- }
-
- // ---------------------------------------
- // Next 2 log methods are not supported in
- // Snowplow Enrichment process yet
-
- /**
- * Log the link or click with the server
- *
- * @param string elementId
- * @param array elementClasses
- * @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(targetUrl, elementId, elementClasses, elementTarget, context) {
- var eventJson = {
- schema: configBaseSchemaPath + '/link_click/jsonschema/1-0-0',
- data: {
- targetUrl: targetUrl,
- elementId: elementId,
- elementClasses: elementClasses,
- elementTarget: elementTarget
- },
- };
-
- logUnstructEvent(eventJson, context);
+ core.trackEcommerceTransactionItem(orderId, sku, name, category, price, quantity, currency, context);
}
/*
@@ -883,7 +766,7 @@
// decodeUrl %xx
sourceHref = unescape(sourceHref);
- logLink(sourceHref, elementId, elementClasses, elementTarget, context);
+ core.trackLinkClick(sourceHref, elementId, elementClasses, elementTarget, context);
}
}
}
@@ -1061,7 +944,7 @@
*/
setAppId: function (appId) {
helpers.warn('setAppId is deprecated. Instead add an "appId" field to the argmap argument of newTracker.');
- configTrackerSiteId = appId;
+ core.setAppId(appId);
},
/**
@@ -1341,7 +1224,7 @@
*/
setPlatform: function(platform) {
helpers.warn('setPlatform is deprecated. Instead add a "platform" field to the argmap argument of newTracker.');
- configPlatform = platform;
+ core.setPlatform(platform);
},
/**
@@ -1352,7 +1235,7 @@
*/
encodeBase64: function (enabled) {
helpers.warn('This usage of encodeBase64 is deprecated. Instead add an "encodeBase64" field to the argmap argument of newTracker.');
- configEncodeBase64 = enabled;
+ core.setBase64Encoding(enabled);
},
/**
@@ -1381,7 +1264,7 @@
* @param object Custom context relating to the event
*/
trackStructEvent: function (category, action, label, property, value, context) {
- logStructEvent(category, action, label, property, value, context);
+ core.trackStructEvent(category, action, label, property, value, context);
},
/**
@@ -1391,7 +1274,7 @@
* @param object context Custom context relating to the event
*/
trackUnstructEvent: function (eventJson, context) {
- logUnstructEvent(eventJson, context);
+ core.trackUnstructEvent(eventJson, context);
},
/**
@@ -1484,10 +1367,6 @@
ecommerceTransaction = ecommerceTransactionTemplate();
},
- // ---------------------------------------
- // Next 2 track events not supported in
- // Snowplow Enrichment process yet
-
/**
* Manually log a click from your own code
*
@@ -1500,7 +1379,7 @@
// TODO: break this into trackLink(destUrl) and trackDownload(destUrl)
trackLinkClick: function(targetUrl, elementId, elementClasses, elementTarget, context) {
trackCallback(function () {
- logLink(targetUrl, elementId, elementClasses, elementTarget, context);
+ core.trackLinkClick(targetUrl, elementId, elementClasses, elementTarget, context);
});
},
@@ -1518,21 +1397,7 @@
*/
trackAdImpression: function(impressionId, costModel, cost, targetUrl, bannerId, zoneId, advertiserId, campaignId, context) {
trackCallback(function () {
- var eventJson = {
- schema: configBaseSchemaPath + '/ad_impression/jsonschema/1-0-0',
- data: {
- impressionId: impressionId,
- costModel: costModel,
- cost: cost,
- bannerId: bannerId,
- targetUrl: targetUrl,
- zoneId: zoneId,
- advertiserId: advertiserId,
- campaignId: campaignId
- }
- };
-
- logUnstructEvent(eventJson, context);
+ core.trackAdImpression(impressionId, costModel, cost, targetUrl, bannerId, zoneId, advertiserId, campaignId, context);
});
},
@@ -1551,22 +1416,7 @@
* @param object Custom context relating to the event
*/
trackAdClick: function(targetUrl, clickId, costModel, cost, bannerId, zoneId, impressionId, advertiserId, campaignId, context) {
- var eventJson = {
- schema: configBaseSchemaPath + '/ad_click/jsonschema/1-0-0',
- data: {
- targetUrl: targetUrl,
- clickId: clickId,
- costModel: costModel,
- cost: cost,
- bannerId: bannerId,
- zoneId: zoneId,
- impressionId: impressionId,
- advertiserId: advertiserId,
- campaignId: campaignId
- }
- };
-
- logUnstructEvent(eventJson, context);
+ core.trackAdClick(targetUrl, clickId, costModel, cost, bannerId, zoneId, impressionId, advertiserId, campaignId, context);
},
/**
@@ -1584,22 +1434,7 @@
* @param object Custom context relating to the event
*/
trackAdConversion: function(conversionId, costModel, cost, category, action, property, initialValue, advertiserId, campaignId, context) {
- var eventJson = {
- schema: configBaseSchemaPath + '/ad_conversion/jsonschema/1-0-0',
- data: {
- conversionId: conversionId,
- costModel: costModel,
- cost: cost,
- category: category,
- action: action,
- property: property,
- initialValue: initialValue,
- advertiserId: advertiserId,
- campaignId: campaignId
- }
- };
-
- logUnstructEvent(eventJson, context);
+ core.trackAdConversion(conversionId, costModel, cost, category, action, property, initialValue, advertiserId, campaignId, context);
}
}
}
From b5c34709f1037113892f93c7b74f83500a14df05 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 10:29:32 +0100
Subject: [PATCH 0029/1059] Stopped outbound queue from triggering multiple
times per event (fixes #251)
---
CHANGELOG | 2 +-
src/js/out_queue.js | 68 ++++++++++++++-------------------------------
2 files changed, 22 insertions(+), 48 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 62775aca4..ee9266b52 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,7 @@
Version 2.1.0 (2014-xx-xx)
--------------------------
Added automated form submission tracking (#252) (TODO)
-Stopped outbound queue from triggering multiple times per event (#251) (TODO)
+Stopped outbound queue from triggering multiple times per event (#251)
Changed default configCookiePath to "/" (#250)
Added RUM / web performance context using HTML5 Web Performance API (#248) (TODO)
Added ability to execute a custom callback once sp.js is loaded (#246)
diff --git a/src/js/out_queue.js b/src/js/out_queue.js
index 09e012ce7..9ffe22f72 100644
--- a/src/js/out_queue.js
+++ b/src/js/out_queue.js
@@ -40,8 +40,7 @@
localStorageAccessible = require('./lib/detectors').localStorageAccessible(),
object = typeof exports !== 'undefined' ? exports : this; // For eventual node.js environment support
- object.OutQueueManager = function(functionName, namespace) {
-
+ object.OutQueueManager = function (functionName, namespace) {
var queueName = ['snowplowOutQueue', functionName, namespace].join('_'),
executingQueue = false,
configCollectorUrl,
@@ -64,7 +63,7 @@
* Queue an image beacon for submission to the collector.
* If we're not processing the queue, we'll start.
*/
- function enqueueRequest(request, url) {
+ function enqueueRequest (request, url) {
outQueue.push(request);
configCollectorUrl = url;
if (localStorageAccessible) {
@@ -80,65 +79,40 @@
* 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() {
+ function executeQueue () {
if (outQueue.length < 1) {
executingQueue = false;
return;
}
- var nextRequest,
- collectorUrl,
- i;
+ // Let's check that we have a Url to ping
+ if (!lodash.isString(configCollectorUrl)) {
+ throw "No Snowplow collector configured, cannot track";
+ }
executingQueue = true;
- for (i in outQueue) {
-
- if (outQueue[i] && outQueue.hasOwnProperty(i)) {
-
- nextRequest = outQueue[i];
-
- // Let's check that we have a Url to ping
- if (!lodash.isString(configCollectorUrl)) {
- throw "No Snowplow collector configured, cannot track";
- }
-
- /*
- * Send image request to the Snowplow Collector using GET.
- * The Collector serves a transparent, single pixel (1x1) GIF
- * Use IIFE to close over i because i may change between setting image.onload and the image loading.
- */
- (function(queueIndex) {
- var image = new Image(1,1);
-
- image.onload = function() {
-
- // We succeeded, let's remove this request from the queue
- delete outQueue[queueIndex];
- if (localStorageAccessible) {
- localStorage.setItem(queueName, json2.stringify(outQueue));
- }
- executeQueue();
- }
+ var nextRequest = outQueue[0];
+ var image = new Image(1, 1);
- image.onerror = function() {}
-
- image.src = configCollectorUrl + nextRequest;
-
- }(i));
+ image.onload = function () {
+ outQueue.shift();
+ if (localStorageAccessible) {
+ localStorage.setItem(queueName, json2.stringify(outQueue));
}
+ executeQueue();
}
- executingQueue = false;
-
- // If every request has been sent, set the queue to []
- if (lodash.compact(outQueue).length === 0) {
- outQueue = [];
+ image.onerror = function () {
+ executingQueue = false;
}
+
+ image.src = configCollectorUrl + nextRequest;
}
- return {
+ return {
enqueueRequest: enqueueRequest
- }
+ };
}
+
}());
From 7b915cddd3d5f283069022d37b21febff0ac9312 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 12:27:29 +0100
Subject: [PATCH 0030/1059] Added social tracking features (fixes #12)
---
CHANGELOG | 2 +-
src/js/tracker.js | 12 ++++++++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index ee9266b52..a9d5d7125 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -21,7 +21,7 @@ Improved F rating for tracker.js in CodeClimate (#150) (TODO)
Clarified scope of localStorage (#122) (TODO)
Added addTo- and removeFrom- Basket events (#97) (TODO)
Added further Intern unit tests (#76) (TODO)
-Added social tracking features (#12) (TODO)
+Added social tracking features (#12)
Improved efficiency of enableLinkClickTracking (#254)
Integrated the Tracker Core (#255)
Removed deprecated trackImpression method (#256)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index b233e4e15..c7f848be7 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -1435,6 +1435,18 @@
*/
trackAdConversion: function(conversionId, costModel, cost, category, action, property, initialValue, advertiserId, campaignId, context) {
core.trackAdConversion(conversionId, costModel, cost, category, action, property, initialValue, advertiserId, campaignId, context);
+ },
+
+ /**
+ * Track a social interaction event
+ *
+ * @param string action (required) Social action performed
+ * @param string network (required) Social network
+ * @param string target Object of the social action e.g. the video liked, the tweet retweeted
+ * @param object Custom context relating to the event
+ */
+ trackSocialInteraction: function(action, network, target, context) {
+ core.trackSocialInteraction(action, network, target, purify(configCustomUrl || locationHrefAlias), context);
}
}
}
From d343800662321552911d9bccc5005beb63ef0f57 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 15:55:07 +0100
Subject: [PATCH 0031/1059] Added trackAddToCart and trackRemoveFromCart events
(closes #97)
---
CHANGELOG | 2 +-
src/js/tracker.js | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index a9d5d7125..773a77caf 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -19,7 +19,7 @@ Replaced "Getting started" with Vagrant-using "Contributing quickstart" (#169) (
Added async-large.html (#162) (TODO)
Improved F rating for tracker.js in CodeClimate (#150) (TODO)
Clarified scope of localStorage (#122) (TODO)
-Added addTo- and removeFrom- Basket events (#97) (TODO)
+Added trackAddToCart and trackRemoveFromCart events (#97)
Added further Intern unit tests (#76) (TODO)
Added social tracking features (#12)
Improved efficiency of enableLinkClickTracking (#254)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index c7f848be7..447a51f9f 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -1447,6 +1447,40 @@
*/
trackSocialInteraction: function(action, network, target, context) {
core.trackSocialInteraction(action, network, target, purify(configCustomUrl || locationHrefAlias), context);
+ },
+
+ /**
+ * Track an add-to-cart event
+ *
+ * @param string sku Required. Item's SKU code.
+ * @param string name Optional. Product name.
+ * @param string category Optional. Product category.
+ * @param string price Required. Product price.
+ * @param string quantity Required. Quantity added.
+ * @param string currency Optional. Product price currency.
+ * @param array context Optional. Context relating to the event.
+ * @param number tstamp Optional. Timestamp of the event
+ * @return object Payload
+ */
+ trackAddToCart: function(sku, name, category, price, quantity, currency, context) {
+ core.trackAddToCart(sku, name, category, price, quantity, currency);
+ },
+
+ /**
+ * Track a remove-from-cart event
+ *
+ * @param string sku Required. Item's SKU code.
+ * @param string name Optional. Product name.
+ * @param string category Optional. Product category.
+ * @param string price Required. Product price.
+ * @param string quantity Required. Quantity removed.
+ * @param string currency Optional. Product price currency.
+ * @param array context Optional. Context relating to the event.
+ * @param number tstamp Optional. Timestamp of the event
+ * @return object Payload
+ */
+ trackRemoveFromCart: function(sku, name, category, price, quantity, currency, context) {
+ core.trackRemoveFromCart(sku, name, category, price, quantity, currency);
}
}
}
From bc6ffc2b14ebdd35086eb6749a778931ffb0ec71 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 16:37:12 +0100
Subject: [PATCH 0032/1059] Removed files rendered unnecessary by #255
---
Gruntfile.js | 1 -
src/js/lib/base64.js | 82 ----------------
src/js/payload.js | 146 ----------------------------
src/js/tracker.js | 1 -
tests/nonfunctional/experimental.js | 64 ++++++++++++
tests/nonfunctional/payload.js | 118 ----------------------
6 files changed, 64 insertions(+), 348 deletions(-)
delete mode 100644 src/js/lib/base64.js
delete mode 100644 src/js/payload.js
create mode 100644 tests/nonfunctional/experimental.js
delete mode 100644 tests/nonfunctional/payload.js
diff --git a/Gruntfile.js b/Gruntfile.js
index b014349ae..9c27cc86e 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -153,7 +153,6 @@ module.exports = function(grunt) {
runType: 'client',
config: 'tests/intern.js',
suites: [
- 'tests/nonfunctional/payload.js',
'tests/nonfunctional/in_queue.js',
'tests/nonfunctional/proxies.js'
]
diff --git a/src/js/lib/base64.js b/src/js/lib/base64.js
deleted file mode 100644
index 715c0e63b..000000000
--- a/src/js/lib/base64.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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/payload.js b/src/js/payload.js
deleted file mode 100644
index 5f3ce47e8..000000000
--- a/src/js/payload.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * JavaScript tracker for Snowplow: payload.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
- lodash = require('./lib_managed/lodash'),
- json2 = require('JSON'),
- base64 = require('./lib/base64'),
-
- object = typeof exports !== 'undefined' ? exports : this; // For eventual node.js environment support
-
- /*
- * Bas64 encode data with URL and Filename Safe Alphabet (base64url)
- *
- * See: http://tools.ietf.org/html/rfc4648#page-7
- */
- function base64urlencode(data) {
- if (!data) return data;
-
- var enc = base64.base64encode(data);
- return enc.replace(/=/g, '')
- .replace(/\+/g, '-')
- .replace(/\//g, '_');
- };
-
- /*
- * Converts a date object to Unix timestamp with or without milliseconds
- */
- function toTimestamp(date, milliseconds) {
- return milliseconds ? date / 1 : Math.floor(date / 1000);
- }
-
- /*
- * Converts a date object to Unix datestamp (number of days since epoch)
- */
- function toDatestamp(date) {
- return Math.floor(date / 86400000);
- }
-
- /*
- * Is property a JSON?
- */
- object.isJson = function (property) {
- return (!lodash.isUndefined(property) && !lodash.isNull(property) &&
- (property.constructor === {}.constructor || property.constructor === [].constructor));
- }
-
- /*
- * Is property a non-empty JSON?
- */
- object.isNonEmptyJson = function (property) {
- if (!object.isJson(property)) {
- return false;
- }
- for (var key in property) {
- if (property.hasOwnProperty(key)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * A helper to build a Snowplow request string from an
- * an optional initial value plus a set of individual
- * name-value pairs, provided using the add method.
- *
- * @param boolean base64Encode Whether or not JSONs should be
- * Base64-URL-safe-encoded
- *
- * @return object The request string builder, with add, addRaw and build methods
- */
- object.payloadBuilder = function (base64Encode) {
- var str = '';
-
- var addNvPair = function (key, value, encode) {
- if (value !== undefined && value !== null && value !== '') {
- var sep = (str.length > 0) ? "&" : "?";
- str += sep + key + '=' + (encode ? encodeURIComponent(value) : value);
- }
- };
-
- var add = function (key, value) {
- addNvPair(key, value, true);
- };
-
- var addRaw = function (key, value) {
- addNvPair(key, value, false);
- };
-
- var addJson = function (keyIfEncoded, keyIfNotEncoded, json) {
-
- if (object.isNonEmptyJson(json)) {
- var str = json2.stringify(json);
-
- if (base64Encode) {
- addRaw(keyIfEncoded, base64urlencode(str));
- } else {
- add(keyIfNotEncoded, str);
- }
- }
- };
-
- return {
- add: add,
- addRaw: addRaw,
- addJson: addJson,
- build: function() {
- return str;
- }
- };
- }
-
-}());
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 447a51f9f..d342898f4 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -40,7 +40,6 @@
proxies = require('./lib/proxies'),
cookie = require('browser-cookie-lite'),
detectors = require('./lib/detectors'),
- payload = require('./payload'),
json2 = require('JSON'),
sha1 = require('sha1'),
requestQueue = require('./out_queue'),
diff --git a/tests/nonfunctional/experimental.js b/tests/nonfunctional/experimental.js
new file mode 100644
index 000000000..8c93a521d
--- /dev/null
+++ b/tests/nonfunctional/experimental.js
@@ -0,0 +1,64 @@
+/*
+ * JavaScript tracker for Snowplow: tests/nonfunctional/payload.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.
+ */
+
+var window = {
+ href: 'http://www.example.com',
+ location: {
+ href: 'http://www.example.com'
+ }
+};
+var document = {
+ domain: 'www.example.com'
+};
+var navigator = {};
+var screen;
+
+define([
+ 'intern!object',
+ 'intern/chai!assert',
+ 'intern/dojo/node!../../src/js/tracker.js'
+], function (registerSuite, assert, tracker) {
+
+ var t = tracker.Tracker("snowplow_function_name", "cf", "js-2.0.1", {}, {});
+
+ registerSuite({
+
+ name: 'Tracker test',
+
+ 'Trial': function() {
+
+
+ }
+ });
+});
diff --git a/tests/nonfunctional/payload.js b/tests/nonfunctional/payload.js
deleted file mode 100644
index aa44ab33b..000000000
--- a/tests/nonfunctional/payload.js
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * JavaScript tracker for Snowplow: tests/nonfunctional/payload.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/payload.js'
-], function (registerSuite, assert, payload) {
-
- var
- sampleJson = [
- {
- schema: "iglu:com.example_company/page/jsonschema/1-2-1",
- data: {
- pageType: 'test',
- lastUpdated: new Date(2014,1,26)
- }
- },
- {
- schema: "iglu:com.example_company/user/jsonschema/2-0-0",
- data: {
- userType: 'tester',
- }
- }
- ]
- expectedStrings = [
- '?e=pv&page=Asynchronous%20website%2Fwebapp%20examples%20for%20snowplow.js',
- '?co=%5B%7B%22schema%22%3A%22iglu%3Acom.example_company%2Fpage%2Fjsonschema%2F1-2-1%22%2C%22data%22%3A%7B%22pageType%22%3A%22test%22%2C%22lastUpdated%22%3A%222014-02-26T00%3A00%3A00.000Z%22%7D%7D%2C%7B%22schema%22%3A%22iglu%3Acom.example_company%2Fuser%2Fjsonschema%2F2-0-0%22%2C%22data%22%3A%7B%22userType%22%3A%22tester%22%7D%7D%5D',
- '?cx=W3sic2NoZW1hIjoiaWdsdTpjb20uZXhhbXBsZV9jb21wYW55L3BhZ2UvanNvbnNjaGVtYS8xLTItMSIsImRhdGEiOnsicGFnZVR5cGUiOiJ0ZXN0IiwibGFzdFVwZGF0ZWQiOiIyMDE0LTAyLTI2VDAwOjAwOjAwLjAwMFoifX0seyJzY2hlbWEiOiJpZ2x1OmNvbS5leGFtcGxlX2NvbXBhbnkvdXNlci9qc29uc2NoZW1hLzItMC0wIiwiZGF0YSI6eyJ1c2VyVHlwZSI6InRlc3RlciJ9fV0'
- ];
-
- registerSuite({
-
- name: 'Payload test',
-
- 'Identify JSON': function() {
- var json = {
- 'name': 'john',
- 'properties': {
- 'age': 30,
- 'languages': ['English', 'French']
- }
- };
-
- assert.strictEqual(payload.isJson(json), true, 'JSON should be identified');
- },
-
- 'Identify non-JSON': function() {
- var nonJson = function(){};
-
- assert.strictEqual(payload.isJson(nonJson), false, 'Non-JSON should be rejected');
- },
-
- 'Identify empty JSON': function() {
- var emptyJson = {};
-
- assert.strictEqual(payload.isNonEmptyJson(emptyJson), false, 'Identify {} as empty')
- },
-
- 'Build payload': function () {
-
- var sb = payload.payloadBuilder(false);
- sb.add('e', 'pv');
- sb.add('page', 'Asynchronous website/webapp examples for snowplow.js');
-
- assert.equal(sb.build(), expectedStrings[0], 'Text should be encoded correctly');
- },
-
- 'Add JSON': function() {
-
- var sb = payload.payloadBuilder(false);
-
- sb.addJson('cx', 'co', sampleJson);
-
- assert.equal(sb.build(), expectedStrings[1], 'JSON should be added correctly');
- },
-
- 'Base 64 encoding': function() {
-
- var sb = payload.payloadBuilder(true);
-
- sb.addJson('cx', 'co', sampleJson);
-
- assert.equal(sb.build(), expectedStrings[2], 'JSON should be encoded correctly');
- }
- });
-});
From f2f1edfd00c2f9078bb042919692857901016af8 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 17:03:31 +0100
Subject: [PATCH 0033/1059] Fixed Code Climate warnings (#150)
---
CHANGELOG | 2 +-
src/js/lib/detectors.js | 46 +++++++++++++--------------
src/js/lib/helpers.js | 16 +++++-----
src/js/snowplow.js | 69 +++++++++++++++++++++--------------------
src/js/tracker.js | 55 ++++++++++++++++----------------
5 files changed, 93 insertions(+), 95 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 773a77caf..1eb803378 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,7 +17,7 @@ Added content field to link click events (#187) (TODO)
Removed dependency on fblundun fork of grunt-yui-compressor (#172) (TODO)
Replaced "Getting started" with Vagrant-using "Contributing quickstart" (#169) (TODO)
Added async-large.html (#162) (TODO)
-Improved F rating for tracker.js in CodeClimate (#150) (TODO)
+Improved F rating for tracker.js in CodeClimate (#150)
Clarified scope of localStorage (#122) (TODO)
Added trackAddToCart and trackRemoveFromCart events (#97)
Added further Intern unit tests (#76) (TODO)
diff --git a/src/js/lib/detectors.js b/src/js/lib/detectors.js
index 32b8d76f8..e8843ef3a 100644
--- a/src/js/lib/detectors.js
+++ b/src/js/lib/detectors.js
@@ -36,7 +36,6 @@
var
lodash = require('../lib_managed/lodash'),
- helpers = require('./helpers'),
murmurhash3_32_gc = require('murmurhash').v3,
tz = require('jstimezonedetect').jstz.determine(),
cookie = require('browser-cookie-lite'),
@@ -59,7 +58,7 @@
} catch (e) {
return true; // SecurityError when referencing it means it exists
}
- }
+ };
/*
* Checks whether localStorage is available, in a way that
@@ -72,26 +71,26 @@
} catch (e) {
return true; // SecurityError when referencing it means it exists
}
- }
+ };
/*
* 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;
- }
- }
+ 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)?
@@ -105,7 +104,7 @@
}
return navigatorAlias.cookieEnabled ? '1' : '0';
- }
+ };
/**
* JS Implementation for browser fingerprint.
@@ -137,15 +136,14 @@
}
}
return murmurhash3_32_gc(fingerprint.join("###") + "###" + plugins.sort().join(";"), hashSeed);
- }
+ };
/*
* Returns visitor timezone
*/
object.detectTimezone = function() {
- //var tz = require('jstimezonedetect').determine(); // For the online version TODO: fix this
- return (typeof (tz) === 'undefined') ? '' : tz.name();
- }
+ return (typeof (tz) === 'undefined') ? '' : tz.name();
+ };
/**
* Gets the current viewport.
@@ -161,7 +159,7 @@
e = documentAlias.documentElement || documentAlias.body;
}
return e[a+'Width'] + 'x' + e[a+'Height'];
- }
+ };
/**
* Gets the dimensions of the current
@@ -175,7 +173,7 @@
var w = Math.max(de.clientWidth, de.offsetWidth, de.scrollWidth);
var h = Math.max(de.clientHeight, de.offsetHeight, de.scrollHeight);
return isNaN(w) || isNaN(h) ? '' : w + 'x' + h;
- }
+ };
/*
* Returns browser features (plugins, resolution, cookies)
@@ -232,6 +230,6 @@
features.cookie = object.hasCookies(testCookieName);
return features;
- }
+ };
}());
diff --git a/src/js/lib/helpers.js b/src/js/lib/helpers.js
index b8533aa5b..661e649e3 100644
--- a/src/js/lib/helpers.js
+++ b/src/js/lib/helpers.js
@@ -51,7 +51,7 @@
}
}
return title;
- }
+ };
/*
* Extract hostname from URL
@@ -62,7 +62,7 @@
matches = e.exec(url);
return matches ? matches[1] : url;
- }
+ };
/*
* Fix-up domain
@@ -79,7 +79,7 @@
domain = domain.slice(1);
}
return domain;
- }
+ };
/*
* Get page referrer
@@ -111,7 +111,7 @@
referrer = document.referrer;
}
return referrer;
- }
+ };
/*
* Cross-browser helper function to add event handler
@@ -125,18 +125,18 @@
return element.attachEvent('on' + eventType, eventHandler);
}
element['on' + eventType] = eventHandler;
- }
+ };
/*
* Return value from name-value pair in querystring
*/
object.fromQuerystring = function (field, url) {
- var match = RegExp('^[^#]*[?&]' + field + '=([^]*)').exec(url);
+ var match = new RegExp('^[^#]*[?&]' + field + '=([^]*)').exec(url);
if (!match) {
return null;
}
return decodeURIComponent(match[1].replace(/\+/g, ' '));
- }
+ };
/*
* Only log deprecation warnings if they won't cause an error
@@ -145,6 +145,6 @@
if (typeof console !== 'undefined') {
console.warn('Snowplow: ' + message);
}
- }
+ };
}());
diff --git a/src/js/snowplow.js b/src/js/snowplow.js
index fb1666200..b2e197653 100644
--- a/src/js/snowplow.js
+++ b/src/js/snowplow.js
@@ -194,40 +194,41 @@
* Public data and methods
************************************************************/
- windowAlias.Snowplow = {
- /**
- * Returns a Tracker object, configured with a
- * CloudFront collector.
- *
- * @param string distSubdomain The subdomain on your CloudFront collector's distribution
- */
- getTrackerCf: function (distSubdomain) {
- var t = new tracker.Tracker(functionName, '', version, mutSnowplowState, {});
- t.setCollectorCf(distSubdomain);
- return t;
- },
-
- /**
- * Returns a Tracker object, configured with the
- * URL to the collector to use.
- *
- * @param string rawUrl The collector URL minus protocol and /i
- */
- getTrackerUrl: function (rawUrl) {
- var t = new tracker.Tracker(functionName, '', version, mutSnowplowState, {});
- t.setCollectorCf(rawUrl);
- return t;
- },
-
- /**
- * Get internal asynchronous tracker object
- *
- * @return Tracker
- */
- getAsyncTracker: function () {
- return new tracker.Tracker(functionName, '', version, mutSnowplowState, {});
- }
- };
+ windowAlias.Snowplow = {
+
+ /**
+ * Returns a Tracker object, configured with a
+ * CloudFront collector.
+ *
+ * @param string distSubdomain The subdomain on your CloudFront collector's distribution
+ */
+ getTrackerCf: function (distSubdomain) {
+ var t = new tracker.Tracker(functionName, '', version, mutSnowplowState, {});
+ t.setCollectorCf(distSubdomain);
+ return t;
+ },
+
+ /**
+ * Returns a Tracker object, configured with the
+ * URL to the collector to use.
+ *
+ * @param string rawUrl The collector URL minus protocol and /i
+ */
+ getTrackerUrl: function (rawUrl) {
+ var t = new tracker.Tracker(functionName, '', version, mutSnowplowState, {});
+ t.setCollectorCf(rawUrl);
+ return t;
+ },
+
+ /**
+ * Get internal asynchronous tracker object
+ *
+ * @return Tracker
+ */
+ getAsyncTracker: function () {
+ return new tracker.Tracker(functionName, '', version, mutSnowplowState, {});
+ }
+ };
/************************************************************
* Constructor
diff --git a/src/js/tracker.js b/src/js/tracker.js
index d342898f4..56d97e446 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -258,7 +258,10 @@
* transaction and line items
*/
function ecommerceTransactionTemplate() {
- return { transaction: {}, items: [] }
+ return {
+ transaction: {},
+ items: []
+ };
}
/*
@@ -390,10 +393,9 @@
*/
function getPageOffsets() {
var iebody = (documentAlias.compatMode && documentAlias.compatMode != "BackCompat") ?
- documentAlias.documentElement :
- documentAlias.body;
- return [iebody.scrollLeft || windowAlias.pageXOffset,
- iebody.scrollTop || windowAlias.pageYOffset];
+ documentAlias.documentElement :
+ documentAlias.body;
+ return [iebody.scrollLeft || windowAlias.pageXOffset, iebody.scrollTop || windowAlias.pageYOffset];
}
/*
@@ -559,10 +561,10 @@
* @return string collectorUrl The tracker URL with protocol
*/
function asCollectorUrl(rawUrl) {
- if(forceSecureTracker)
+ if (forceSecureTracker)
return ('https' + '://' + rawUrl + '/i');
else
- return ('https:' == documentAlias.location.protocol ? 'https' : 'http') + '://' + rawUrl + '/i';
+ return ('https:' === documentAlias.location.protocol ? 'https' : 'http') + '://' + rawUrl + '/i';
}
/**
@@ -648,15 +650,15 @@
/**
* Log ecommerce transaction metadata
*
- * @param string orderId
- * @param string affiliation
- * @param string total
- * @param string tax
- * @param string shipping
+ * @param string orderId
+ * @param string affiliation
+ * @param string total
+ * @param string tax
+ * @param string shipping
* @param string city
- * @param string state
- * @param string country
- * @param string currency The currency the total/tax/shipping are expressed in
+ * @param string state
+ * @param string country
+ * @param string currency The currency the total/tax/shipping are expressed in
* @param object context Custom context relating to the event
*/
function logTransaction(orderId, affiliation, total, tax, shipping, city, state, country, currency, context) {
@@ -1124,10 +1126,7 @@
* @param int heartBeatDelay Seconds to wait between pings
*/
enableActivityTracking: function (minimumVisitLength, heartBeatDelay) {
-
- var now = new Date();
-
- configMinimumVisitTime = now.getTime() + minimumVisitLength * 1000;
+ configMinimumVisitTime = new Date().getTime() + minimumVisitLength * 1000;
configHeartBeatTimer = heartBeatDelay * 1000;
},
@@ -1174,27 +1173,27 @@
*
* @param string queryName Name of a querystring name-value pair
*/
- setUserIdFromLocation: function(querystringField) {
- businessUserId = helpers.fromQuerystring(querystringField, locationHrefAlias);
- },
+ setUserIdFromLocation: function(querystringField) {
+ businessUserId = helpers.fromQuerystring(querystringField, locationHrefAlias);
+ },
/**
* Set the business-defined user ID for this user using the referrer querystring.
*
* @param string queryName Name of a querystring name-value pair
*/
- setUserIdFromReferrer: function(querystringField) {
- businessUserId = helpers.fromQuerystring(querystringField, configReferrerUrl);
- },
+ setUserIdFromReferrer: function(querystringField) {
+ businessUserId = helpers.fromQuerystring(querystringField, configReferrerUrl);
+ },
/**
* Set the business-defined user ID for this user to the value of a cookie.
*
* @param string cookieName Name of the cookie whose value will be assigned to businessUserId
*/
- setUserIdFromCookie: function(cookieName) {
- businessUserId = cookie.cookie(cookieName);
- },
+ setUserIdFromCookie: function(cookieName) {
+ businessUserId = cookie.cookie(cookieName);
+ },
/**
* Configure this tracker to log to a CloudFront collector.
From f2f9d307d3caeab1d0dd98f8a2d0b372f667ec92 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Tue, 30 Sep 2014 17:38:22 +0100
Subject: [PATCH 0034/1059] Moved context querystring to end of JS-generated
beacons (fixes #204)
---
CHANGELOG | 3 ++-
src/js/tracker.js | 12 +++++++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 1eb803378..f8aeef7c1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,7 +10,7 @@ Improved document height detection (#236) (TODO)
Fixed SauceLabs red status (#235) (TODO)
Fixed CloudFront cache invalidation (#230) (TODO)
Renamed /dist to /deploy (#216)
-Moved context querystring to end of JS-generated beacons (#204) (TODO)
+Moved context querystring to end of JS-generated beacons (#204)
Added pageUnloadGuard to wait until outbound queue is empty before unloading (#202) (TODO)
Added event_id generation (#190)
Added content field to link click events (#187) (TODO)
@@ -25,6 +25,7 @@ Added social tracking features (#12)
Improved efficiency of enableLinkClickTracking (#254)
Integrated the Tracker Core (#255)
Removed deprecated trackImpression method (#256)
+Added forceSecureTracker boolean option to the argmap, thanks @kujo4pmZ! (#247) (TODO)
Version 2.0.2 (2014-10-20)
--------------------------
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 56d97e446..4c3dfcd34 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -320,12 +320,15 @@
/*
* Convert a dictionary to a querystring
+ * The context field is the last in the querystring
*/
function getQuerystring(request) {
var querystring = '?',
+ lowPriorityKeys = {'co': true, 'cx': true},
firstPair = true;
+
for (var key in request) {
- if (request.hasOwnProperty(key)) {
+ if (request.hasOwnProperty(key) && !(lowPriorityKeys.hasOwnProperty(key))) {
if (!firstPair) {
querystring += '&';
} else {
@@ -334,6 +337,13 @@
querystring += encodeURIComponent(key) + '=' + encodeURIComponent(request[key]);
}
}
+
+ for (var contextKey in lowPriorityKeys) {
+ if (request.hasOwnProperty(contextKey) && lowPriorityKeys.hasOwnProperty(contextKey)) {
+ querystring += '&' + contextKey + '=' + request[contextKey];
+ }
+ }
+
return querystring;
}
From b81797a34eca96955d1b1235c7dbe83739d19bb7 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 1 Oct 2014 15:26:14 +0100
Subject: [PATCH 0035/1059] Added automated form submission tracking (closes
#252)
---
CHANGELOG | 4 +-
Gruntfile.js | 2 +-
src/js/tracker.js | 112 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 115 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index f8aeef7c1..a88159b40 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,6 @@
Version 2.1.0 (2014-xx-xx)
--------------------------
-Added automated form submission tracking (#252) (TODO)
+Added automated form submission tracking (#252)
Stopped outbound queue from triggering multiple times per event (#251)
Changed default configCookiePath to "/" (#250)
Added RUM / web performance context using HTML5 Web Performance API (#248) (TODO)
@@ -25,7 +25,7 @@ Added social tracking features (#12)
Improved efficiency of enableLinkClickTracking (#254)
Integrated the Tracker Core (#255)
Removed deprecated trackImpression method (#256)
-Added forceSecureTracker boolean option to the argmap, thanks @kujo4pmZ! (#247) (TODO)
+Added forceSecureTracker boolean option to the argmap, thanks @kujo4pmZ! (#247)
Version 2.0.2 (2014-10-20)
--------------------------
diff --git a/Gruntfile.js b/Gruntfile.js
index 9c27cc86e..0e3379fb0 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -82,7 +82,7 @@ module.exports = function(grunt) {
dest: 'src/js/lib_managed/lodash.js',
options: {
exports: 'node',
- include: 'isArray, isFunction, isString, isObject, isDate, isUndefined, isNull, map, compact, isEmpty',
+ include: 'isArray, isFunction, isString, isObject, isDate, isUndefined, isNull, map, filter, compact, isEmpty',
flags: ['debug']
}
}
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 4c3dfcd34..0c5d3831e 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -228,8 +228,16 @@
// Will be committed, sent and emptied by a call to trackTrans.
ecommerceTransaction = ecommerceTransactionTemplate(),
+ // Element types relevant to form tracking
+ formTrackingNodeNames = {
+ 'INPUT': true,
+ 'TEXTAREA': true,
+ 'SELECT': true
+ },
+
outQueueManager = new requestQueue.OutQueueManager(functionName, namespace);
+
// Enable base 64 encoding for unstructured events and custom contexts
core.setBase64Encoding(argmap.hasOwnProperty('encodeBase64') ? argmap.encodeBase64 : true);
@@ -904,6 +912,93 @@
}
}
+ /*
+ * Get an identifier for a form, input, textarea, or select element
+ */
+ function getFormElementName(elt) {
+ return elt.name || elt.id || elt.type || elt.nodeName;
+ }
+
+ /*
+ * Identifies the parent form in which an element is contained
+ */
+ function getParentFormName(elt) {
+ while (elt && elt.nodeName.toUpperCase() !== 'HTML' && elt.nodeName.toUpperCase() !== 'FORM') {
+ elt = elt.parentNode;
+ }
+ if (elt.nodeName.toUpperCase() === 'FORM') {
+ return getFormElementName(elt);
+ }
+ }
+
+ /*
+ * Returns a list of the input, textarea, and select elements inside a form along with their values
+ */
+ function getInnerFormElements(elt) {
+ return lodash.map(lodash.filter(elt.children, function (child) {
+
+ // Only include mutable inner elements
+ return formTrackingNodeNames[child.nodeName.toUpperCase()] && child.type !== 'submit';
+ }), function (child) {
+ var elementJson = {
+ name: getFormElementName(child),
+ value: child.value,
+ nodeName: child.nodeName,
+ };
+ if (child.type && child.nodeName.toUpperCase() === 'INPUT') {
+ elementJson.type = child.type;
+ }
+ return elementJson;
+ });
+ }
+
+ /*
+ * Return function to handle form field change event
+ */
+ function getFormChangeListener(context) {
+ return function (e) {
+ var elt = e.target;
+ var type = elt.nodeName.toUpperCase() === 'INPUT' ? elt.type : null;
+ core.trackFormChange(getParentFormName(elt), getFormElementName(elt), elt.nodeName, type, lodash.map(elt.classList), elt.value, context);
+ };
+ }
+
+ /*
+ * Return function to handle form submission event
+ */
+ function getFormSubmissionListener(context) {
+ return function (e) {
+ var elt = e.target;
+ var innerElements = getInnerFormElements(elt);
+ core.trackFormSubmission(getFormElementName(elt), lodash.map(elt.classList), innerElements, context);
+ };
+ }
+
+ /*
+ * Add submission event listeners to all form elements
+ * Add value change event listeners to all mutable inner form elements
+ */
+ function addFormListeners (context) {
+ var innerElementTags = ['textarea', 'input', 'select'];
+ var trackingMarker = trackerId + 'form';
+
+ lodash.map(innerElementTags, function (tagname) {
+ lodash.map(document.getElementsByTagName(tagname), function (innerElement) {
+ if (!innerElement[trackingMarker]) {
+ helpers.addEventListener(innerElement, 'change', getFormChangeListener(context), false);
+ innerElement[trackingMarker] = true;
+ }
+ });
+ });
+
+ lodash.map(document.getElementsByTagName('form'), function (form) {
+ if (!form[trackingMarker]) {
+ helpers.addEventListener(form, 'submit', getFormSubmissionListener(context));
+ form[trackingMarker] = true;
+ }
+ });
+ }
+
/************************************************************
* Constructor
************************************************************/
@@ -1140,6 +1235,23 @@
configHeartBeatTimer = heartBeatDelay * 1000;
},
+ /**
+ * Enables automatic form tracking.
+ * An event will be fired when a form field is changed or a form submitted.
+ * This can be called multiple times: only forms not already tracked will be tracked.
+ *
+ * @param array context Context for all form tracking events
+ */
+ enableFormTracking: function (context) {
+ if (mutSnowplowState.hasLoaded) {
+ addFormListeners(context);
+ } else {
+ mutSnowplowState.registeredOnLoadHandlers.push(function () {
+ addFormListeners(context);
+ });
+ }
+ },
+
/**
* Frame buster
*/
From 3e4e7fea9a4f38f9987d632578c102b3955be556 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Wed, 1 Oct 2014 17:15:39 +0100
Subject: [PATCH 0036/1059] Added RUM / web performance context using HTML5 Web
Performance API (closes #248)
---
CHANGELOG | 2 +-
examples/web/async-medium.html | 2 +-
examples/web/async-small.html | 2 +-
src/js/tracker.js | 19 +++++++++++++++----
4 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index a88159b40..9741f83e8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,7 +3,7 @@ Version 2.1.0 (2014-xx-xx)
Added automated form submission tracking (#252)
Stopped outbound queue from triggering multiple times per event (#251)
Changed default configCookiePath to "/" (#250)
-Added RUM / web performance context using HTML5 Web Performance API (#248) (TODO)
+Added RUM / web performance context using HTML5 Web Performance API (#248)
Added ability to execute a custom callback once sp.js is loaded (#246)
Added internal site search event (#241) (TODO)
Improved document height detection (#236) (TODO)
diff --git a/examples/web/async-medium.html b/examples/web/async-medium.html
index 136f57c16..a4c3d62ae 100644
--- a/examples/web/async-medium.html
+++ b/examples/web/async-medium.html
@@ -53,7 +53,7 @@
}
}, true);
// window.new_name_here('trackPageView', 'Async Test'); // Track the page view with custom title
- window.new_name_here('trackPageView', null , [ // Auto-set page title; add page context
+ window.new_name_here('trackPageView', null, true, [ // Auto-set page title; add page context
{
schema: "iglu:com.example_company/page/jsonschema/1-2-1",
data: {
diff --git a/examples/web/async-small.html b/examples/web/async-small.html
index f6d042899..0edde4f08 100644
--- a/examples/web/async-small.html
+++ b/examples/web/async-small.html
@@ -38,7 +38,7 @@
window.snowplow('enableActivityTracking', 10, 10); // Ping every 10 seconds after 10 seconds
window.snowplow('enableLinkClickTracking', {blacklist: ['barred']}, true); // Track clicks on links whose class is not "barred"
// window.snowplow('trackPageView', 'Async Test'); // Track the page view with custom title
- window.snowplow('trackPageView', null , [ // Auto-set page title; add page context
+ window.snowplow('trackPageView', null , true, [ // Auto-set page title; add page context
{
schema: "iglu:com.example_company/page/jsonschema/1-2-1",
data: {
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 0c5d3831e..4f2a3d893 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -589,13 +589,22 @@
* Log the page view / visit
*
* @param string customTitle The user-defined page title to attach to this page view
+ * @param bool performanceTracking Whether to create a custom context with performance.timing data
* @param object context Custom context relating to the event
*/
- function logPageView(customTitle, context) {
+ function logPageView(customTitle, performanceTracking, context) {
// Fixup page title. We'll pass this to logPagePing too.
var pageTitle = helpers.fixupTitle(customTitle || configTitle);
+ if (performanceTracking && windowAlias.performance && windowAlias.performance.timing) {
+ context = context || [];
+ context.push({
+ schema: 'iglu:org.w3/PerformanceTiming/jsonschema/1-0-0',
+ data: windowAlias.performance.timing
+ });
+ }
+
// Log page view
core.trackPageView(purify(configCustomUrl || locationHrefAlias), pageTitle, purify(configReferrerUrl), context);
@@ -1351,7 +1360,7 @@
*
* Enable Base64 encoding for unstructured event payload
*
- * @param boolean enabled A boolean value indicating if the Base64 encoding for unstructured events should be enabled or not
+ * @param bool enabled A boolean value indicating if the Base64 encoding for unstructured events should be enabled or not
*/
encodeBase64: function (enabled) {
helpers.warn('This usage of encodeBase64 is deprecated. Instead add an "encodeBase64" field to the argmap argument of newTracker.');
@@ -1362,11 +1371,13 @@
* Log visit to this page
*
* @param string customTitle
+ * @param bool performanceTracking Whether to create a custom context with performance.timing data
* @param object Custom context relating to the event
*/
- trackPageView: function (customTitle, context) {
+ trackPageView: function (customTitle, performanceTracking, context) {
+ console.log(window.performance.timing.domContentLoadedEventEnd- window.performance.timing.navigationStart);
trackCallback(function () {
- logPageView(customTitle, context);
+ logPageView(customTitle, performanceTracking, context);
});
},
From 3e881e02f46492d5a8f14fed3c88bab466bd7f63 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 2 Oct 2014 09:13:46 +0100
Subject: [PATCH 0037/1059] Added checks for possible aliases for
window.performance (#248)
---
CHANGELOG | 2 +-
src/js/tracker.js | 16 +++++++++-------
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 9741f83e8..33dd4e0f7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,7 +3,7 @@ Version 2.1.0 (2014-xx-xx)
Added automated form submission tracking (#252)
Stopped outbound queue from triggering multiple times per event (#251)
Changed default configCookiePath to "/" (#250)
-Added RUM / web performance context using HTML5 Web Performance API (#248)
+Added PerformanceTiming context using HTML5 Web Performance API (#248)
Added ability to execute a custom callback once sp.js is loaded (#246)
Added internal site search event (#241) (TODO)
Improved document height detection (#236) (TODO)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 4f2a3d893..6a4fbfb35 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -597,12 +597,15 @@
// Fixup page title. We'll pass this to logPagePing too.
var pageTitle = helpers.fixupTitle(customTitle || configTitle);
- if (performanceTracking && windowAlias.performance && windowAlias.performance.timing) {
- context = context || [];
- context.push({
- schema: 'iglu:org.w3/PerformanceTiming/jsonschema/1-0-0',
- data: windowAlias.performance.timing
- });
+ if (performanceTracking) {
+ var performance = windowAlias.performance || windowAlias.mozPerformance || windowAlias.msPerformance || windowAlias.webkitPerformance;
+ if (performance) {
+ context = context || [];
+ context.push({
+ schema: 'iglu:org.w3/PerformanceTiming/jsonschema/1-0-0',
+ data: performance.timing
+ });
+ }
}
// Log page view
@@ -1375,7 +1378,6 @@
* @param object Custom context relating to the event
*/
trackPageView: function (customTitle, performanceTracking, context) {
- console.log(window.performance.timing.domContentLoadedEventEnd- window.performance.timing.navigationStart);
trackCallback(function () {
logPageView(customTitle, performanceTracking, context);
});
From 37c27f5a7bbcc66f60dcdda5d548828c03029984 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 2 Oct 2014 09:32:32 +0100
Subject: [PATCH 0038/1059] Added content field to link click events (closes
#187)
---
CHANGELOG | 2 +-
examples/web/async-medium.html | 2 +-
src/js/tracker.js | 20 ++++++++++++++------
3 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 33dd4e0f7..56145576c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -13,7 +13,7 @@ Renamed /dist to /deploy (#216)
Moved context querystring to end of JS-generated beacons (#204)
Added pageUnloadGuard to wait until outbound queue is empty before unloading (#202) (TODO)
Added event_id generation (#190)
-Added content field to link click events (#187) (TODO)
+Added content field to link click events (#187)
Removed dependency on fblundun fork of grunt-yui-compressor (#172) (TODO)
Replaced "Getting started" with Vagrant-using "Contributing quickstart" (#169) (TODO)
Added async-large.html (#162) (TODO)
diff --git a/examples/web/async-medium.html b/examples/web/async-medium.html
index a4c3d62ae..432a0f3ae 100644
--- a/examples/web/async-medium.html
+++ b/examples/web/async-medium.html
@@ -46,7 +46,7 @@
//window.new_name_here('setUserIdFromCookie', '_sp_id.4209') // Test this using Firefox because Chrome doesn't allow local cookies.
window.new_name_here('setCustomUrl', '/overridden-url/'); // Override the page URL
window.new_name_here('enableActivityTracking', 10, 10); // Ping every 10 seconds after 10 seconds
- window.new_name_here('enableLinkClickTracking:cf', {whitelist: ['inbound', 'out']}, true); // Track clicks on links whose class is not "barred"
+ window.new_name_here('enableLinkClickTracking:cf', {whitelist: ['inbound', 'out']}, true, true); // Track clicks on links whose class is not "barred"
window.new_name_here('enableLinkClickTracking:uri', {
filter: function(link){
return link.id === 'legal';
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 6a4fbfb35..cb2469c32 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -190,6 +190,9 @@
// Whether pseudo clicks are tracked
linkTrackingPseudoClicks,
+ // Whether to track the innerHTML of clicked links
+ linkTrackingContent,
+
// The context attached to link click events
linkTrackingContext,
@@ -773,7 +776,8 @@
tag,
elementId,
elementClasses,
- elementTarget;
+ elementTarget,
+ elementContent;
while ((parentElement = sourceElement.parentNode) !== null &&
!lodash.isUndefined(parentElement) && // buggy IE5.5
@@ -794,10 +798,11 @@
elementId = sourceElement.id;
elementClasses = lodash.map(sourceElement.classList);
elementTarget = sourceElement.target;
+ elementContent = linkTrackingContent ? sourceElement.innerHTML : null;
// decodeUrl %xx
sourceHref = unescape(sourceHref);
- core.trackLinkClick(sourceHref, elementId, elementClasses, elementTarget, context);
+ core.trackLinkClick(sourceHref, elementId, elementClasses, elementTarget, elementContent, context);
}
}
}
@@ -883,12 +888,13 @@
* Configures link click tracking: how to filter which links will be tracked,
* whether to use pseudo click tracking, and what context to attach to link_click events
*/
- function configureLinkClickTracking(criterion, pseudoClicks, context) {
+ function configureLinkClickTracking(criterion, pseudoClicks, trackContent, context) {
var specifiedClasses,
inclusive,
specifiedClassesSet,
i;
+ linkTrackingContent = trackContent;
linkTrackingContext = context;
linkTrackingPseudoClicks = pseudoClicks;
@@ -1212,16 +1218,18 @@
*
* @param object criterion Criterion by which it will be decided whether a link will be tracked
* @param bool pseudoClicks If true, use pseudo click-handler (mousedown+mouseup)
+ * @param bool trackContent Whether to track the innerHTML of the link element
+ * @param array context Context for all link click events
*/
- enableLinkClickTracking: function (criterion, pseudoClicks, context) {
+ enableLinkClickTracking: function (criterion, pseudoClicks, trackContent, context) {
if (mutSnowplowState.hasLoaded) {
// the load event has already fired, add the click listeners now
- configureLinkClickTracking(criterion, pseudoClicks, context);
+ configureLinkClickTracking(criterion, pseudoClicks, trackContent, context);
addClickListeners();
} else {
// defer until page has loaded
mutSnowplowState.registeredOnLoadHandlers.push(function () {
- configureLinkClickTracking(criterion, pseudoClicks, context);
+ configureLinkClickTracking(criterion, pseudoClicks, trackContent, context);
addClickListeners();
});
}
From 4e6ccb6482a10d1e3da824f0c5ee5b9adad7f708 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 2 Oct 2014 10:30:34 +0100
Subject: [PATCH 0039/1059] Added internal site search event (closes #241)
---
CHANGELOG | 2 +-
src/js/tracker.js | 17 +++++++++++++----
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 56145576c..e91fe7439 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,7 +5,7 @@ Stopped outbound queue from triggering multiple times per event (#251)
Changed default configCookiePath to "/" (#250)
Added PerformanceTiming context using HTML5 Web Performance API (#248)
Added ability to execute a custom callback once sp.js is loaded (#246)
-Added internal site search event (#241) (TODO)
+Added internal site search event (#241)
Improved document height detection (#236) (TODO)
Fixed SauceLabs red status (#235) (TODO)
Fixed CloudFront cache invalidation (#230) (TODO)
diff --git a/src/js/tracker.js b/src/js/tracker.js
index cb2469c32..36f66caf9 100644
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -1600,8 +1600,6 @@
* @param string quantity Required. Quantity added.
* @param string currency Optional. Product price currency.
* @param array context Optional. Context relating to the event.
- * @param number tstamp Optional. Timestamp of the event
- * @return object Payload
*/
trackAddToCart: function(sku, name, category, price, quantity, currency, context) {
core.trackAddToCart(sku, name, category, price, quantity, currency);
@@ -1617,11 +1615,22 @@
* @param string quantity Required. Quantity removed.
* @param string currency Optional. Product price currency.
* @param array context Optional. Context relating to the event.
- * @param number tstamp Optional. Timestamp of the event
- * @return object Payload
*/
trackRemoveFromCart: function(sku, name, category, price, quantity, currency, context) {
core.trackRemoveFromCart(sku, name, category, price, quantity, currency);
+ },
+
+ /**
+ * Track an internal search event
+ *
+ * @param array terms Search terms
+ * @param array filters Search filters
+ * @param totalResults Number of results
+ * @param pageResults Number of results displayed on page
+ * @param array context Optional. Context relating to the event.
+ */
+ trackSiteSearch: function(terms, filters, totalResults, pageResults, context) {
+ core.trackSiteSearch(terms, filters, totalResults, pageResults, context);
}
}
}
From b7e3ca3e5acab2b293d5e8327716baa507f2e9ca Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 2 Oct 2014 11:17:04 +0100
Subject: [PATCH 0040/1059] Added async-large.html (closes #162)
---
CHANGELOG | 2 +-
examples/web/async-large.html | 188 ++++++++++++++++++++++++++++++++++
2 files changed, 189 insertions(+), 1 deletion(-)
create mode 100644 examples/web/async-large.html
diff --git a/CHANGELOG b/CHANGELOG
index e91fe7439..02dd3e5bf 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,7 +16,7 @@ Added event_id generation (#190)
Added content field to link click events (#187)
Removed dependency on fblundun fork of grunt-yui-compressor (#172) (TODO)
Replaced "Getting started" with Vagrant-using "Contributing quickstart" (#169) (TODO)
-Added async-large.html (#162) (TODO)
+Added async-large.html (#162)
Improved F rating for tracker.js in CodeClimate (#150)
Clarified scope of localStorage (#122) (TODO)
Added trackAddToCart and trackRemoveFromCart events (#97)
diff --git a/examples/web/async-large.html b/examples/web/async-large.html
new file mode 100644
index 000000000..699c4d9a1
--- /dev/null
+++ b/examples/web/async-large.html
@@ -0,0 +1,188 @@
+
+
+
+
+ Large asynchronous website/webapp examples for snowplow.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Large_asynchronous_examples_for_snowplow.js
+ This shows how two users can simultaneously use Snowplow on the same page without any clash
+ Press the buttons below to trigger individual tracking events:
+
+
+
+
+
+ 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
+
+
+
+
From 8da17647a0314a02d5e296cd00505dbb7eaa9d72 Mon Sep 17 00:00:00 2001
From: Fred Blundun
Date: Thu, 2 Oct 2014 11:54:44 +0100
Subject: [PATCH 0041/1059] Added new events and form tracking to
async-large.html (#162)
---
examples/web/async-large.html | 54 +++++++++++++++++++++++++++++++++--
1 file changed, 52 insertions(+), 2 deletions(-)
diff --git a/examples/web/async-large.html b/examples/web/async-large.html
index 699c4d9a1..0772e2bcd 100644
--- a/examples/web/async-large.html
+++ b/examples/web/async-large.html
@@ -37,6 +37,7 @@
window.snowplow_1('setCustomUrl', '/overridden-url/'); // Override the page URL
window.snowplow_1('enableActivityTracking', 10, 10); // Ping every 10 seconds after 10 seconds
window.snowplow_1('enableLinkClickTracking', {blacklist: ['barred']}, true); // Track clicks on links whose class is not "barred"
+ window.snowplow_1('enableFormTracking'); // Track changes to form fields and form submissions
// window.snowplow_1('trackPageView', 'Async Test'); // Track the page view with custom title
window.snowplow_1('trackPageView', null , false, [ // Auto-set page title; add page context
{
@@ -164,7 +165,41 @@
// trackTrans sends the transaction to Snowplow tracking servers.
// Must be called last to commit the transaction.
window.snowplow_1('trackTrans');
+ }
+
+ function addToCart () {
+ alert('adding some items to the cart');
+ window.snowplow_1('trackAddToCart',
+ 'Blue hat', // SKU - required
+ 'clothing', // category
+ 500, // price - required
+ 2, // quantity added - required
+ 'GBP' // currency
+ );
+ }
+
+ function removeFromCart () {
+ alert('removing an item from the cart');
+ window.snowplow_1('trackRemoveFromCart', '1008', 'Blue hat', 'clothing', '500', '1', 'GBP');
+ }
+
+ function likeVideo () {
+ alert('tracking a social interaction')
+ window.snowplow_1('trackSocialInteraction',
+ 'like', // action - required
+ 'facebook', // network - required
+ 'video-003254' // target of action
+ );
+ }
+ function searchSite () {
+ alert('Searching the site');
+ window.snowplow_1('trackSiteSearch',
+ ['event', 'analytics'], // search terms - required
+ ['books', 'safe search'], // search filters
+ 15, // number of results returned
+ 10 // number of results displayed on page
+ );
}
@@ -176,12 +211,27 @@ This shows how two users can simultaneously use Snowplow on the same page wi
-
+
+
+
+
+
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
+ Link ignored by one user
+
+
+
+