Both trackers will track this link
- Only the cf tracker will track this link
+ Only the sp tracker will track this link Neither tracker will track this link
diff --git a/examples/web/async-small.html b/examples/web/async-small.html
index b4dd8ac15..4f1345697 100644
--- a/examples/web/async-small.html
+++ b/examples/web/async-small.html
@@ -25,9 +25,9 @@
};p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1;
n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","../sp.js","snowplow"));
- window.snowplow('newTracker', 'cf', '<>', { // Initialise a tracker
+ window.snowplow('newTracker', 'sp', '<>', { // Initialise a tracker
encodeBase64: false, // Default is true
- appId: 'CFe23a', // Site ID can be anything you want. Set it if you're tracking more than one site in this account
+ appId: 'my-app-id', // Site ID can be anything you want. Set it if you're tracking more than one site in this account
platform: 'mob',
contexts: {
webPage: true,
@@ -80,7 +80,7 @@
function viewProduct() {
alert("Viewing a product");
- window.snowplow('trackUnstructEvent', {
+ window.snowplow('trackSelfDescribingEvent', {
schema: 'iglu:com.acme_company/viewed_product/jsonschema/5-0-0',
data: {
productId: 'ASO01043',
diff --git a/examples/web/cookieless.html b/examples/web/cookieless.html
index 18d2de77c..6335c8f8e 100644
--- a/examples/web/cookieless.html
+++ b/examples/web/cookieless.html
@@ -35,11 +35,11 @@
}
})(window, document, 'script', '../sp.js', 'snowplow')
- window.snowplow('newTracker', 'cf', '127.0.0.1:9090', {
+ window.snowplow('newTracker', 'sp', '127.0.0.1:9090', {
// Initialise a tracker
anonymousTracking: true,
encodeBase64: false, // Default is true
- appId: 'CFe23a', // Site ID can be anything you want. Set it if you're tracking more than one site in this account
+ appId: 'my-app-id', // Site ID can be anything you want. Set it if you're tracking more than one site in this account
platform: 'mob',
contexts: {
webPage: true,
@@ -102,7 +102,7 @@
Cookieless_tracking_examples_for_snowplow.js
}
function login() {
- window.snowplow('enableUserTracking', 'localStorage')
+ window.snowplow('disableAnonymousTracking', 'cookieAndLocalStorage')
window.snowplow('setUserId', 'alex 123') // Business-defined user ID
window.snowplow('setUserIdFromLocation', 'id') // To test this, reload the page with ?id=xxx
window.snowplow('setUserIdFromCookie', '_sp_id.4209') // Test this using Firefox because Chrome doesn't allow local cookies.
@@ -114,7 +114,7 @@
Warning: if your browser's Do Not Track feature is enabled and respectDoNotTrack is enabled, all tracking will be prevented.
-
If you are viewing the page using a file URL, you must edit the script URL in the Snowplow tag to include an http scheme. Otherwise a file scheme will be inferred and the page will attempt to load sp.js from the local filesystem..
-
Press the buttons below to trigger individual tracking events:
-
-
-
-
-
-
-
diff --git a/src/js/in_queue.js b/src/js/in_queue.js
index 70a8110cb..1ecc10d16 100644
--- a/src/js/in_queue.js
+++ b/src/js/in_queue.js
@@ -73,30 +73,6 @@ export function InQueueManager(TrackerConstructor, version, mutSnowplowState, as
return namedTrackers;
}
- /**
- * Legacy support for input of the form _snaq.push(['setCollectorCf', 'd34uzc5hjrimh8'])
- *
- * @param string f Either 'setCollectorCf' or 'setCollectorUrl'
- * @param string endpoint
- * @param string namespace Optional tracker name
- *
- * TODO: remove this in 2.1.0
- */
- function legacyCreateNewNamespace(f, endpoint, namespace) {
- warn(f + ' is deprecated. Set the collector when a new tracker instance using newTracker.');
-
- var name;
-
- if (isUndefined(namespace)) {
- name = 'sp';
- } else {
- name = namespace;
- }
-
- createNewNamespace(name);
- trackerDictionary[name][f](endpoint);
- }
-
/**
* Initiate a new tracker namespace
*
@@ -165,11 +141,6 @@ export function InQueueManager(TrackerConstructor, version, mutSnowplowState, as
continue;
}
- if ((f === 'setCollectorCf' || f === 'setCollectorUrl') && (!names || names.length === 0)) {
- legacyCreateNewNamespace(f, parameterArray[0], parameterArray[1]);
- continue;
- }
-
namedTrackers = getNamedTrackers(names);
for (j = 0; j < namedTrackers.length; j++) {
diff --git a/src/js/init.js b/src/js/init.js
index 5eacf4d1c..bcc369fff 100644
--- a/src/js/init.js
+++ b/src/js/init.js
@@ -44,11 +44,6 @@ var queueName,
queue,
windowAlias = window;
-if (windowAlias.GlobalSnowplowNamespace && windowAlias.GlobalSnowplowNamespace.length > 0) {
- queueName = windowAlias.GlobalSnowplowNamespace.shift();
- queue = windowAlias[queueName];
- queue.q = new Snowplow(queue.q, queueName);
-} else {
- windowAlias._snaq = windowAlias._snaq || [];
- windowAlias._snaq = new Snowplow(windowAlias._snaq, '_snaq');
-}
+queueName = windowAlias.GlobalSnowplowNamespace.shift();
+queue = windowAlias[queueName];
+queue.q = new Snowplow(queue.q, queueName);
diff --git a/src/js/lib/proxies.js b/src/js/lib/proxies.js
index 10b87bc5a..06ad9da10 100644
--- a/src/js/lib/proxies.js
+++ b/src/js/lib/proxies.js
@@ -34,33 +34,6 @@
import { fromQuerystring, getHostName } from './helpers';
-/*
- * Test whether a string is an IP address
- */
-function isIpAddress(string) {
- var IPRegExp = new RegExp(
- '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
- );
- return IPRegExp.test(string);
-}
-
-/*
- * If the hostname is an IP address, look for text indicating
- * that the page is cached by Yahoo
- */
-function isYahooCachedPage(hostName) {
- var initialDivText, cachedIndicator;
- if (isIpAddress(hostName)) {
- try {
- initialDivText = document.body.children[0].children[0].children[0].children[0].children[0].children[0].innerHTML;
- cachedIndicator = 'You have reached the cached page for';
- return initialDivText.slice(0, cachedIndicator.length) === cachedIndicator;
- } catch (e) {
- return false;
- }
- }
-}
-
/*
* Extract parameter from URL
*/
@@ -86,11 +59,9 @@ export function fixupUrl(hostName, href, referrer) {
href = getParameter(href, 'u');
hostName = getHostName(href);
} else if (
- hostName === 'cc.bingj.com' || // Bing
- hostName === 'webcache.googleusercontent.com' || // Google
- isYahooCachedPage(hostName)
+ hostName === 'cc.bingj.com' || // Bing & Yahoo
+ hostName === 'webcache.googleusercontent.com' // Google
) {
- // Yahoo (via Inktomi 74.6.0.0/16)
href = document.links[0].href;
hostName = getHostName(href);
}
diff --git a/src/js/snowplow.js b/src/js/snowplow.js
index d8689bdbc..c0b2bc496 100644
--- a/src/js/snowplow.js
+++ b/src/js/snowplow.js
@@ -32,45 +32,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*jslint browser:true, plusplus:true, vars:true, nomen:true, evil:true */
-/*global window */
-/*global unescape */
-/*global ActiveXObject */
-/*global _snaq:true */
-/*members encodeURIComponent, decodeURIComponent, getElementsByTagName,
- shift, unshift,
- addEventListener, attachEvent, removeEventListener, detachEvent,
- cookie, domain, readyState, documentElement, doScroll, title, text,
- location, top, document, referrer, parent, links, href, protocol, GearsFactory,
- event, which, button, srcElement, type, target,
- parentNode, tagName, hostname, className,
- userAgent, cookieEnabled, platform, mimeTypes, enabledPlugin, javaEnabled,
- XDomainRequest, XMLHttpRequest, ActiveXObject, open, setRequestHeader, onreadystatechange, setRequestHeader, send, readyState, status,
- getTime, getTimeAlias, setTime, toGMTString, getHours, getMinutes, getSeconds,
- toLowerCase, charAt, indexOf, lastIndexOf, split, slice, toUpperCase,
- onload, src,
- round, random,
- exec,
- res, width, height,
- pdf, qt, realp, wma, dir, fla, java, gears, ag,
- hook, getHook,
- setCollectorCf, setCollectorUrl, setAppId,
- setDownloadExtensions, addDownloadExtensions,
- setDomains, setIgnoreClasses, setRequestMethod,
- setReferrerUrl, setCustomUrl, setDocumentTitle,
- setDownloadClasses, setLinkClasses,
- discardHashTag,
- setCookieNamePrefix, setCookieDomain, setCookiePath, setVisitorIdCookie,
- setVisitorCookieTimeout, setSessionCookieTimeout, setReferralCookieTimeout,
- doNotTrack, respectDoNotTrack, msDoNotTrack, getTimestamp, getCookieValue,
- detectTimezone, detectViewport,
- addListener, enableLinkTracking, enableActivityTracking, setLinkTrackingTimer,
- enableDarkSocialTracking,
- killFrame, redirectFile, setCountPreRendered,
- trackLink, trackPageView, trackImpression,
- addPlugin, getAsyncTracker
-*/
-
import forEach from 'lodash/forEach';
import { addEventListener } from './lib/helpers';
import { InQueueManager } from './in_queue';
@@ -202,45 +163,6 @@ export function Snowplow(asynchronousQueue, functionName) {
addEventListener(windowAlias, 'load', loadHandler, false);
}
- /************************************************************
- * 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(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(functionName, '', version, mutSnowplowState, {});
- t.setCollectorUrl(rawUrl);
- return t;
- },
-
- /**
- * Get internal asynchronous tracker object
- *
- * @return Tracker
- */
- getAsyncTracker: function () {
- return new Tracker(functionName, '', version, mutSnowplowState, {});
- },
- };
-
/************************************************************
* Constructor
************************************************************/
diff --git a/src/js/tracker.js b/src/js/tracker.js
index 042a045a7..631eff6c7 100755
--- a/src/js/tracker.js
+++ b/src/js/tracker.js
@@ -52,7 +52,7 @@ import {
parseAndValidateFloat,
parseAndValidateInt,
cookie,
- deleteCookie
+ deleteCookie,
} from './lib/helpers';
import { fixupUrl } from './lib/proxies';
import { detectBrowserFeatures, detectTimezone, detectViewport, detectDocumentSize } from './lib/detectors';
@@ -84,25 +84,22 @@ import uuid from 'uuid/v4';
* 8. pageUnloadTimer, 500
* 9. forceSecureTracker, false
* 10. forceUnsecureTracker, false
- * 11. useLocalStorage, true
- * 12. useCookies, true
- * 13. sessionCookieTimeout, 1800
- * 14. contexts, {}
- * 15. eventMethod, 'post'
- * 16. post, false *DEPRECATED use eventMethod instead*
- * 17. postPath, null
- * 18. useStm, true
- * 19. bufferSize, 1
- * 20. crossDomainLinker, false
- * 21. maxPostBytes, 40000
- * 22. discoverRootDomain, false
- * 23. cookieLifetime, 63072000
- * 24. stateStorageStrategy, 'cookieAndLocalStorage'
- * 25. maxLocalStorageQueueSize, 1000
- * 26. resetActivityTrackingOnPageView, true
- * 27. connectionTimeout, 5000
- * 28. skippedBrowserFeatures, []
- * 29. anonymousTracking, false // bool | { withSessionTracking: bool, withServerAnonymisation: bool }
+ * 11. sessionCookieTimeout, 1800
+ * 12. contexts, {}
+ * 13. eventMethod, 'post'
+ * 14. postPath, null
+ * 15. useStm, true
+ * 16. bufferSize, 1
+ * 17. crossDomainLinker, false
+ * 18. maxPostBytes, 40000
+ * 19. discoverRootDomain, false
+ * 20. cookieLifetime, 63072000
+ * 21. stateStorageStrategy, 'cookieAndLocalStorage'
+ * 22. maxLocalStorageQueueSize, 1000
+ * 23. resetActivityTrackingOnPageView, true
+ * 24. connectionTimeout, 5000
+ * 25. skippedBrowserFeatures, []
+ * 26. anonymousTracking, false // bool | { withSessionTracking: bool, withServerAnonymisation: bool }
*/
export function Tracker(functionName, namespace, version, mutSnowplowState, argmap) {
/************************************************************
@@ -111,12 +108,8 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
var argmap = argmap || {};
- //use POST if that property is present on the argmap
- if (argmap.hasOwnProperty('post')) {
- argmap.eventMethod = argmap.post === true ? 'post' : 'get';
- } else {
- argmap.eventMethod = argmap.eventMethod || 'post';
- }
+ //use POST if eventMethod isn't present on the argmap
+ argmap.eventMethod = argmap.eventMethod || 'post';
// attach stm to GET requests by default
if (!argmap.hasOwnProperty('useStm')) {
@@ -124,15 +117,7 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
}
const getStateStorageStrategy = (config) =>
- config.hasOwnProperty('stateStorageStrategy')
- ? config.stateStorageStrategy
- : !configUseCookies && !configUseLocalStorage
- ? 'none'
- : configUseCookies && configUseLocalStorage
- ? 'cookieAndLocalStorage'
- : configUseCookies
- ? 'cookie'
- : 'localStorage';
+ config.hasOwnProperty('stateStorageStrategy') ? config.stateStorageStrategy : 'cookieAndLocalStorage';
const getAnonymousSessionTracking = (config) =>
config.hasOwnProperty('anonymousTracking') ? config.anonymousTracking.withSessionTracking === true : false;
@@ -222,8 +207,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
: false,
// Opt out of cookie tracking
configOptOutCookie,
- // Count sites which are pre-rendered
- configCountPreRendered,
// Life of the visitor cookie (in seconds)
configVisitorCookieTimeout = argmap.hasOwnProperty('cookieLifetime') ? argmap.cookieLifetime : 63072000, // 2 years
// Life of the session cookie (in seconds)
@@ -243,14 +226,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
configAnonymousServerTracking = getAnonymousServerTracking(argmap),
// Sets tracker to work in anonymous mode without accessing client storage
configAnonymousTracking = getAnonymousTracking(argmap),
- // Whether to use localStorage to store events between sessions while offline
- configUseLocalStorage = argmap.hasOwnProperty('useLocalStorage')
- ? (warn('argmap.useLocalStorage is deprecated. Use argmap.stateStorageStrategy instead.'), argmap.useLocalStorage)
- : true,
- // Whether to use cookies
- configUseCookies = argmap.hasOwnProperty('useCookies')
- ? (warn('argmap.useCookies is deprecated. Use argmap.stateStorageStrategy instead.'), argmap.useCookies)
- : true,
// Strategy defining how to store the state: cookie, localStorage, cookieAndLocalStorage or none
configStateStorageStrategy = getStateStorageStrategy(argmap),
// Browser language (or Windows language for IE). Imperfect but CloudFront doesn't log the Accept-Language header
@@ -852,18 +827,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
lastEventTime = new Date().getTime();
}
- /**
- * Builds a collector URL from a CloudFront distribution.
- * We don't bother to support custom CNAMEs because Amazon CloudFront doesn't support that for SSL.
- *
- * @param string account The account ID to build the tracker URL from
- *
- * @return string The URL on which the collector is hosted
- */
- function collectorUrlFromCfDist(distSubdomain) {
- return asCollectorUrl(distSubdomain + '.cloudfront.net');
- }
-
/**
* Adds the protocol in front of our collector URL, and i to the end
*
@@ -1783,67 +1746,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
);
}
- /**
- * Construct a browser prefix
- *
- * E.g: (moz, hidden) -> mozHidden
- */
- function prefixPropertyName(prefix, propertyName) {
- if (prefix !== '') {
- return prefix + propertyName.charAt(0).toUpperCase() + propertyName.slice(1);
- }
-
- return propertyName;
- }
-
- /**
- * Check for pre-rendered web pages, and log the page view/link
- * according to the configuration and/or visibility
- *
- * @see http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html
- */
- function trackCallback(callback) {
- var isPreRendered,
- i,
- // Chrome 13, IE10, FF10
- prefixes = ['', 'webkit', 'ms', 'moz'],
- prefix;
-
- // If configPrerendered == true - we'll never set `isPreRendered` to true and fire immediately,
- // otherwise we need to check if this is just prerendered
- if (!configCountPreRendered) {
- // true by default
-
- for (i = 0; i < prefixes.length; i++) {
- prefix = prefixes[i];
-
- // does this browser support the page visibility API? (drop this check along with IE9 and iOS6)
- if (documentAlias[prefixPropertyName(prefix, 'hidden')]) {
- // if pre-rendered, then defer callback until page visibility changes
- if (documentAlias[prefixPropertyName(prefix, 'visibilityState')] === 'prerender') {
- isPreRendered = true;
- }
- break;
- } else if (documentAlias[prefixPropertyName(prefix, 'hidden')] === false) {
- break;
- }
- }
- }
-
- // Implies configCountPreRendered = false
- if (isPreRendered) {
- // note: the event name doesn't follow the same naming convention as vendor properties
- addEventListener(documentAlias, prefix + 'visibilitychange', function ready() {
- documentAlias.removeEventListener(prefix + 'visibilitychange', ready, false);
- callback();
- });
- return;
- }
-
- // configCountPreRendered === true || isPreRendered === false
- callback();
- }
-
/**
* Update the returned methods (public facing methods)
*/
@@ -1874,10 +1776,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* Public data and methods
************************************************************/
- const userFingerprintingWarning =
- 'User Fingerprinting is no longer supported. This function will be removed in a future release.';
- const argmapDeprecationWarning = ' is deprecated. Instead use the argmap argument on tracker initialisation: ';
-
/**
* Get the domain session index also known as current memorized visit count.
*
@@ -1938,26 +1836,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
return loadDomainUserIdCookie();
};
- /**
- * Get the user fingerprint
- *
- * @return string The user fingerprint
- */
- apiMethods.getUserFingerprint = function () {
- warn(userFingerprintingWarning);
- return 0;
- };
-
- /**
- * Specify the app ID
- *
- * @param int|string appId
- */
- apiMethods.setAppId = function (appId) {
- warn('setAppId' + argmapDeprecationWarning + 'appId');
- core.setAppId(appId);
- };
-
/**
* Override referrer
*
@@ -2006,27 +1884,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
configDiscardBrace = enableFilter;
};
- /**
- * Set first-party cookie name prefix
- *
- * @param string cookieNamePrefix
- */
- apiMethods.setCookieNamePrefix = function (cookieNamePrefix) {
- warn('setCookieNamePrefix' + argmapDeprecationWarning + 'cookieName');
- configCookieNamePrefix = cookieNamePrefix;
- };
-
- /**
- * Set first-party cookie domain
- *
- * @param string domain
- */
- apiMethods.setCookieDomain = function (domain) {
- warn('setCookieDomain' + argmapDeprecationWarning + 'cookieDomain');
- configCookieDomain = fixupDomain(domain);
- updateDomainHash();
- };
-
/**
* Set first-party cookie path
*
@@ -2046,44 +1903,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
configVisitorCookieTimeout = timeout;
};
- /**
- * Set session cookie timeout (in seconds)
- *
- * @param int timeout
- */
- apiMethods.setSessionCookieTimeout = function (timeout) {
- warn('setSessionCookieTimeout' + argmapDeprecationWarning + 'sessionCookieTimeout');
- configSessionCookieTimeout = timeout;
- };
-
- /**
- * @param number seed The seed used for MurmurHash3
- */
- apiMethods.setUserFingerprintSeed = function () {
- warn(userFingerprintingWarning);
- };
-
- /**
- * Enable/disable user fingerprinting. User fingerprinting is enabled by default.
- */
- apiMethods.enableUserFingerprint = function () {
- warn(userFingerprintingWarning);
- };
-
- /**
- * Prevent tracking if user's browser has Do Not Track feature enabled,
- * where tracking is:
- * 1) Sending events to a collector
- * 2) Setting first-party cookies
- * @param bool enable If true and Do Not Track feature enabled, don't track.
- */
- apiMethods.respectDoNotTrack = function (enable) {
- warn('respectDoNotTrack' + argmapDeprecationWarning + 'respectDoNotTrack');
- var dnt = navigatorAlias.doNotTrack || navigatorAlias.msDoNotTrack;
-
- configDoNotTrack = enable && (dnt === 'yes' || dnt === '1');
- };
-
/**
* Enable querystring decoration for links pasing a filter
*
@@ -2202,26 +2021,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
}
};
- /**
- * Frame buster
- */
- apiMethods.killFrame = function () {
- if (windowAlias.location !== windowAlias.top.location) {
- windowAlias.top.location = windowAlias.location;
- }
- };
-
- /**
- * Redirect if browsing offline (aka file: buster)
- *
- * @param string url Redirect to this URL
- */
- apiMethods.redirectFile = function (url) {
- if (windowAlias.location.protocol === 'file:') {
- windowAlias.location = url;
- }
- };
-
/**
* Sets the opt out cookie.
*
@@ -2231,15 +2030,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
configOptOutCookie = name;
};
- /**
- * Count sites in pre-rendered state
- *
- * @param bool enable If true, track when in pre-rendered state
- */
- apiMethods.setCountPreRendered = function (enable) {
- configCountPreRendered = enable;
- };
-
/**
* Set the business-defined user ID for this user.
*
@@ -2287,16 +2077,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
businessUserId = cookie(cookieName);
};
- /**
- * Configure this tracker to log to a CloudFront collector.
- *
- * @param string distSubdomain The subdomain on your CloudFront collector's distribution
- */
- apiMethods.setCollectorCf = function (distSubdomain) {
- configCollectorUrl = collectorUrlFromCfDist(distSubdomain);
- outQueue.setCollectorUrl(configCollectorUrl);
- };
-
/**
*
* Specify the Snowplow collector URL. No need to include HTTP
@@ -2309,27 +2089,6 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
outQueue.setCollectorUrl(configCollectorUrl);
};
- /**
- * Specify the platform
- *
- * @param string platform Overrides the default tracking platform
- */
- apiMethods.setPlatform = function (platform) {
- warn('setPlatform' + argmapDeprecationWarning + 'platform');
- core.setPlatform(platform);
- };
-
- /**
- *
- * Enable Base64 encoding for self-describing event payload
- *
- * @param bool enabled A boolean value indicating if the Base64 encoding for self-describing events should be enabled or not
- */
- apiMethods.encodeBase64 = function (enabled) {
- warn('encodeBase64' + argmapDeprecationWarning + 'encodeBase64');
- core.setBase64Encoding(enabled);
- };
-
/**
* Send all events in the outQueue
* Use only when sending POSTs with a bufferSize of at least 2
@@ -2341,7 +2100,7 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
/**
* Add the geolocation context to all events
*/
- apiMethods.enableGeolocationContext = enableGeolocationContext,
+ apiMethods.enableGeolocationContext = enableGeolocationContext;
/**
* Log visit to this page
@@ -2353,9 +2112,7 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* @param function afterTrack (optional) A callback function triggered after event is tracked
*/
apiMethods.trackPageView = function (customTitle, context, contextCallback, tstamp, afterTrack) {
- trackCallback(function () {
- logPageView(customTitle, context, contextCallback, tstamp, afterTrack);
- });
+ logPageView(customTitle, context, contextCallback, tstamp, afterTrack);
};
/**
@@ -2374,13 +2131,11 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* @param function afterTrack (optional) A callback function triggered after event is tracked
*/
apiMethods.trackStructEvent = function (category, action, label, property, value, context, tstamp, afterTrack) {
- trackCallback(function () {
- core.trackStructEvent(category, action, label, property, value, addCommonContexts(context), tstamp, afterTrack);
- });
+ core.trackStructEvent(category, action, label, property, value, addCommonContexts(context), tstamp, afterTrack);
};
/**
- * Track a self-describing event (previously unstructured event) happening on this page.
+ * Track a self-describing event happening on this page.
*
* @param object eventJson Contains the properties and schema location for the event
* @param object context Custom context relating to the event
@@ -2388,18 +2143,7 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* @param function afterTrack (optional) A callback function triggered after event is tracked
*/
apiMethods.trackSelfDescribingEvent = function (eventJson, context, tstamp, afterTrack) {
- trackCallback(function () {
- core.trackSelfDescribingEvent(eventJson, addCommonContexts(context), tstamp, afterTrack);
- });
- };
-
- /**
- * Alias for `trackSelfDescribingEvent`, left for compatibility
- */
- apiMethods.trackUnstructEvent = function (eventJson, context, tstamp) {
- trackCallback(function () {
- core.trackSelfDescribingEvent(eventJson, addCommonContexts(context), tstamp);
- });
+ core.trackSelfDescribingEvent(eventJson, addCommonContexts(context), tstamp, afterTrack);
};
/**
@@ -2479,37 +2223,35 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* addItem methods to the tracking server.
*/
apiMethods.trackTrans = function () {
- trackCallback(function () {
- logTransaction(
- ecommerceTransaction.transaction.orderId,
- ecommerceTransaction.transaction.affiliation,
- ecommerceTransaction.transaction.total,
- ecommerceTransaction.transaction.tax,
- ecommerceTransaction.transaction.shipping,
- ecommerceTransaction.transaction.city,
- ecommerceTransaction.transaction.state,
- ecommerceTransaction.transaction.country,
- ecommerceTransaction.transaction.currency,
- ecommerceTransaction.transaction.context,
- ecommerceTransaction.transaction.tstamp
+ logTransaction(
+ ecommerceTransaction.transaction.orderId,
+ ecommerceTransaction.transaction.affiliation,
+ ecommerceTransaction.transaction.total,
+ ecommerceTransaction.transaction.tax,
+ ecommerceTransaction.transaction.shipping,
+ ecommerceTransaction.transaction.city,
+ ecommerceTransaction.transaction.state,
+ ecommerceTransaction.transaction.country,
+ ecommerceTransaction.transaction.currency,
+ ecommerceTransaction.transaction.context,
+ ecommerceTransaction.transaction.tstamp
+ );
+ for (var i = 0; i < ecommerceTransaction.items.length; i++) {
+ var item = ecommerceTransaction.items[i];
+ logTransactionItem(
+ item.orderId,
+ item.sku,
+ item.name,
+ item.category,
+ item.price,
+ item.quantity,
+ item.currency,
+ item.context,
+ item.tstamp
);
- for (var i = 0; i < ecommerceTransaction.items.length; i++) {
- var item = ecommerceTransaction.items[i];
- logTransactionItem(
- item.orderId,
- item.sku,
- item.name,
- item.category,
- item.price,
- item.quantity,
- item.currency,
- item.context,
- item.tstamp
- );
- }
+ }
- ecommerceTransaction = ecommerceTransactionTemplate();
- });
+ ecommerceTransaction = ecommerceTransactionTemplate();
};
/**
@@ -2533,17 +2275,15 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
context,
tstamp
) {
- trackCallback(function () {
- core.trackLinkClick(
- targetUrl,
- elementId,
- elementClasses,
- elementTarget,
- elementContent,
- addCommonContexts(context),
- tstamp
- );
- });
+ core.trackLinkClick(
+ targetUrl,
+ elementId,
+ elementClasses,
+ elementTarget,
+ elementContent,
+ addCommonContexts(context),
+ tstamp
+ );
};
/**
@@ -2571,20 +2311,18 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
context,
tstamp
) {
- trackCallback(function () {
- core.trackAdImpression(
- impressionId,
- costModel,
- cost,
- targetUrl,
- bannerId,
- zoneId,
- advertiserId,
- campaignId,
- addCommonContexts(context),
- tstamp
- );
- });
+ core.trackAdImpression(
+ impressionId,
+ costModel,
+ cost,
+ targetUrl,
+ bannerId,
+ zoneId,
+ advertiserId,
+ campaignId,
+ addCommonContexts(context),
+ tstamp
+ );
};
/**
@@ -2615,21 +2353,19 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
context,
tstamp
) {
- trackCallback(function () {
- core.trackAdClick(
- targetUrl,
- clickId,
- costModel,
- cost,
- bannerId,
- zoneId,
- impressionId,
- advertiserId,
- campaignId,
- addCommonContexts(context),
- tstamp
- );
- });
+ core.trackAdClick(
+ targetUrl,
+ clickId,
+ costModel,
+ cost,
+ bannerId,
+ zoneId,
+ impressionId,
+ advertiserId,
+ campaignId,
+ addCommonContexts(context),
+ tstamp
+ );
};
/**
@@ -2660,21 +2396,19 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
context,
tstamp
) {
- trackCallback(function () {
- core.trackAdConversion(
- conversionId,
- costModel,
- cost,
- category,
- action,
- property,
- initialValue,
- advertiserId,
- campaignId,
- addCommonContexts(context),
- tstamp
- );
- });
+ core.trackAdConversion(
+ conversionId,
+ costModel,
+ cost,
+ category,
+ action,
+ property,
+ initialValue,
+ advertiserId,
+ campaignId,
+ addCommonContexts(context),
+ tstamp
+ );
};
/**
@@ -2687,9 +2421,7 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* @param tstamp number or Timestamp object
*/
apiMethods.trackSocialInteraction = function (action, network, target, context, tstamp) {
- trackCallback(function () {
- core.trackSocialInteraction(action, network, target, addCommonContexts(context), tstamp);
- });
+ core.trackSocialInteraction(action, network, target, addCommonContexts(context), tstamp);
};
/**
@@ -2705,9 +2437,7 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* @param tstamp number or Timestamp object
*/
apiMethods.trackAddToCart = function (sku, name, category, unitPrice, quantity, currency, context, tstamp) {
- trackCallback(function () {
- core.trackAddToCart(sku, name, category, unitPrice, quantity, currency, addCommonContexts(context), tstamp);
- });
+ core.trackAddToCart(sku, name, category, unitPrice, quantity, currency, addCommonContexts(context), tstamp);
};
/**
@@ -2723,9 +2453,7 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* @param tstamp Opinal number or Timestamp object
*/
apiMethods.trackRemoveFromCart = function (sku, name, category, unitPrice, quantity, currency, context, tstamp) {
- trackCallback(function () {
- core.trackRemoveFromCart(sku, name, category, unitPrice, quantity, currency, addCommonContexts(context), tstamp);
- });
+ core.trackRemoveFromCart(sku, name, category, unitPrice, quantity, currency, addCommonContexts(context), tstamp);
};
/**
@@ -2739,9 +2467,7 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* @param tstamp Opinal number or Timestamp object
*/
apiMethods.trackSiteSearch = function (terms, filters, totalResults, pageResults, context, tstamp) {
- trackCallback(function () {
- core.trackSiteSearch(terms, filters, totalResults, pageResults, addCommonContexts(context), tstamp);
- });
+ core.trackSiteSearch(terms, filters, totalResults, pageResults, addCommonContexts(context), tstamp);
};
/**
@@ -2755,21 +2481,19 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* @param tstamp Opinal number or Timestamp object
*/
apiMethods.trackTiming = function (category, variable, timing, label, context, tstamp) {
- trackCallback(function () {
- core.trackSelfDescribingEvent(
- {
- schema: 'iglu:com.snowplowanalytics.snowplow/timing/jsonschema/1-0-0',
- data: {
- category: category,
- variable: variable,
- timing: timing,
- label: label,
- },
+ core.trackSelfDescribingEvent(
+ {
+ schema: 'iglu:com.snowplowanalytics.snowplow/timing/jsonschema/1-0-0',
+ data: {
+ category: category,
+ variable: variable,
+ timing: timing,
+ label: label,
},
- addCommonContexts(context),
- tstamp
- );
- });
+ },
+ addCommonContexts(context),
+ tstamp
+ );
};
/**
@@ -2784,9 +2508,7 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* @param {number|Timestamp} [tstamp] - Number or Timestamp object.
*/
apiMethods.trackConsentWithdrawn = function (all, id, version, name, description, context, tstamp) {
- trackCallback(function () {
- core.trackConsentWithdrawn(all, id, version, name, description, addCommonContexts(context), tstamp);
- });
+ core.trackConsentWithdrawn(all, id, version, name, description, addCommonContexts(context), tstamp);
};
/**
@@ -2801,9 +2523,7 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
* @param {Timestamp|number} [tstamp] - number or Timestamp object.
*/
apiMethods.trackConsentGranted = function (id, version, name, description, expiry, context, tstamp) {
- trackCallback(function () {
- core.trackConsentGranted(id, version, name, description, expiry, addCommonContexts(context), tstamp);
- });
+ core.trackConsentGranted(id, version, name, description, expiry, addCommonContexts(context), tstamp);
};
/**
@@ -2818,18 +2538,16 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
var combinedEnhancedEcommerceContexts = enhancedEcommerceContexts.concat(context || []);
enhancedEcommerceContexts.length = 0;
- trackCallback(function () {
- core.trackSelfDescribingEvent(
- {
- schema: 'iglu:com.google.analytics.enhanced-ecommerce/action/jsonschema/1-0-0',
- data: {
- action: action,
- },
+ core.trackSelfDescribingEvent(
+ {
+ schema: 'iglu:com.google.analytics.enhanced-ecommerce/action/jsonschema/1-0-0',
+ data: {
+ action: action,
},
- addCommonContexts(combinedEnhancedEcommerceContexts),
- tstamp
- );
- });
+ },
+ addCommonContexts(combinedEnhancedEcommerceContexts),
+ tstamp
+ );
};
/**
@@ -2999,7 +2717,7 @@ export function Tracker(functionName, namespace, version, mutSnowplowState, argm
if (!basis) {
warn(
- 'enableGdprContext failed. basisForProcessing must be set to one of: consent, legalObligation, vitalInterests publicTask, legitimateInterests'
+ 'enableGdprContext: basisForProcessing must be one of: consent, legalObligation, vitalInterests publicTask, legitimateInterests'
);
return;
} else {
diff --git a/tests/integration/integration.spec.js b/tests/integration/integration.spec.js
index c47f37e36..041b47362 100755
--- a/tests/integration/integration.spec.js
+++ b/tests/integration/integration.spec.js
@@ -209,7 +209,7 @@ describe('Snowplow Micro integration', () => {
).toBe(true)
})
- it(`${method}: contains an unstructured event with true timestamp`, () => {
+ it(`${method}: contains an self describing event with true timestamp`, () => {
expect(
logContains({
event: {
@@ -290,7 +290,7 @@ describe('Snowplow Micro integration', () => {
const pageViews = F.filter(
ev =>
F.get('event.event', ev) === 'page_view' &&
- F.get('event.name_tracker', ev) === 'cf',
+ F.get('event.name_tracker', ev) === 'sp',
log
)
@@ -360,7 +360,7 @@ describe('Snowplow Micro integration', () => {
).toBe(true)
})
- it(`${method}: contains an unstructured event with global context from accept ruleset`, () => {
+ it(`${method}: contains an self describing event with global context from accept ruleset`, () => {
expect(
logContains({
event: {
@@ -382,7 +382,7 @@ describe('Snowplow Micro integration', () => {
).toBe(true)
})
- it(`${method}: contains an unstructured event missing global context from reject ruleset`, () => {
+ it(`${method}: contains an self describing event missing global context from reject ruleset`, () => {
expect(
logContains({
event: {
diff --git a/tests/pages/activity-callback.html b/tests/pages/activity-callback.html
index ef778e416..93d297c28 100644
--- a/tests/pages/activity-callback.html
+++ b/tests/pages/activity-callback.html
@@ -14,7 +14,7 @@
};p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1;
n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","./snowplow.js","snowplow"));
- snowplow('newTracker', 'cf', 'snowplow-js-tracker.local:9090');
+ snowplow('newTracker', 'sp', 'snowplow-js-tracker.local:9090');
snowplow(function() {
document.getElementById('init').innerText = 'true';
});
@@ -68,7 +68,7 @@
function getCurrentPageViewId(cb) {
snowplow(function() {
- cb(this.cf.getPageViewId())
+ cb(this.sp.getPageViewId())
});
}
diff --git a/tests/pages/integration.html b/tests/pages/integration.html
index eb9dfb2c0..619622be4 100644
--- a/tests/pages/integration.html
+++ b/tests/pages/integration.html
@@ -37,7 +37,7 @@
var eventMethod = parseQuery().eventMethod;
- window.snowplow('newTracker', 'cf', collector_endpoint, {
+ window.snowplow('newTracker', 'sp', collector_endpoint, {
appId: 'sp-' + eventMethod,
platform: 'mob',
eventMethod: eventMethod,
@@ -86,17 +86,17 @@
return {};
}
- window.snowplow('enableGdprContext:cf', 'consent', 'someId', '0.1.0', 'this document is a test');
+ window.snowplow('enableGdprContext:sp', 'consent', 'someId', '0.1.0', 'this document is a test');
- window.snowplow('addGlobalContexts:cf', [erroneousContextGenerator]);
- window.snowplow('addGlobalContexts:cf', [[structuredEventFilter, [eventTypeContextGenerator, geolocationContext]]]);
+ window.snowplow('addGlobalContexts:sp', [erroneousContextGenerator]);
+ window.snowplow('addGlobalContexts:sp', [[structuredEventFilter, [eventTypeContextGenerator, geolocationContext]]]);
- window.snowplow('setUserId:cf', 'Malcolm');
+ window.snowplow('setUserId:sp', 'Malcolm');
- window.snowplow('enableActivityTracking:cf', 1, 2);
+ window.snowplow('enableActivityTracking:sp', 1, 2);
// Also tracks to non-base64 encoding tracker
- window.snowplow('trackPageView:cf;b64off', 'My Title', [ // Set page title; add page context
+ window.snowplow('trackPageView:sp;b64off', 'My Title', [ // Set page title; add page context
{
schema: "iglu:org.schema/WebPage/jsonschema/1-0-0",
data: {
@@ -106,10 +106,10 @@
]);
// This should have different pageViewId in web_page context
- window.snowplow('trackPageView:cf');
+ window.snowplow('trackPageView:sp');
- window.snowplow('trackStructEvent:cf', 'Mixes', 'Play', 'MRC/fabric-0503-mix', '', '0.0');
- window.snowplow('trackUnstructEvent:cf', {
+ window.snowplow('trackStructEvent:sp', 'Mixes', 'Play', 'MRC/fabric-0503-mix', '', '0.0');
+ window.snowplow('trackUnstructEvent:sp', {
schema: 'iglu:com.snowplowanalytics.snowplow/ad_impression/jsonschema/1-0-0',
data: {
bannerId: 'ASO01043'
@@ -118,7 +118,7 @@
var orderId = 'order-123';
- window.snowplow('addTrans:cf',
+ window.snowplow('addTrans:sp',
orderId,
'acme',
'8000',
@@ -131,7 +131,7 @@
);
// addItem might be called for each item in the shopping cart, or not at all.
- window.snowplow('addItem:cf',
+ window.snowplow('addItem:sp',
orderId,
'1001',
'Blue t-shirt',
@@ -143,7 +143,7 @@
// trackTrans sends the transaction to Snowplow tracking servers.
// Must be called last to commit the transaction.
- window.snowplow('trackTrans:cf');
+ window.snowplow('trackTrans:sp');
var testAcceptRuleSet = {
accept: ['iglu:com.snowplowanalytics.snowplow/*/jsonschema/*-*-*']
@@ -153,28 +153,28 @@
};
// test context rulesets
- window.snowplow('addGlobalContexts:cf', [[testAcceptRuleSet, [eventTypeContextGenerator, geolocationContext]]]);
+ window.snowplow('addGlobalContexts:sp', [[testAcceptRuleSet, [eventTypeContextGenerator, geolocationContext]]]);
- window.snowplow('trackUnstructEvent:cf', {
+ window.snowplow('trackUnstructEvent:sp', {
schema: 'iglu:com.snowplowanalytics.snowplow/ad_impression/jsonschema/1-0-0',
data: {
bannerId: 'ASO01042'
}
}, [], {type: 'ttm', value: 1477401869});
- window.snowplow('removeGlobalContexts:cf', [[testAcceptRuleSet, [eventTypeContextGenerator, geolocationContext]]]);
+ window.snowplow('removeGlobalContexts:sp', [[testAcceptRuleSet, [eventTypeContextGenerator, geolocationContext]]]);
- window.snowplow('addGlobalContexts:cf', [[testRejectRuleSet, [eventTypeContextGenerator, geolocationContext]]]);
- window.snowplow('trackUnstructEvent:cf', {
+ window.snowplow('addGlobalContexts:sp', [[testRejectRuleSet, [eventTypeContextGenerator, geolocationContext]]]);
+ window.snowplow('trackUnstructEvent:sp', {
schema: 'iglu:com.snowplowanalytics.snowplow/ad_impression/jsonschema/1-0-0',
data: {
bannerId: 'ASO01041'
}
}, [], {type: 'ttm', value: 1477401868});
- window.snowplow('trackSocialInteraction:cf', 'retweet', 'twitter', '1234');
+ window.snowplow('trackSocialInteraction:sp', 'retweet', 'twitter', '1234');
- window.snowplow('trackAdImpression:cf',
+ window.snowplow('trackAdImpression:sp',
'67965967893',
'cpm',
5.5,
@@ -185,7 +185,7 @@
'12'
);
- window.snowplow('trackAdClick:cf',
+ window.snowplow('trackAdClick:sp',
'http://www.example.com', // targetUrl
'12243253', // clickId
'cpm', // costModel
@@ -197,7 +197,7 @@
'12' // campaignId
);
- window.snowplow('trackAdConversion:cf',
+ window.snowplow('trackAdConversion:sp',
'743560297', // conversionId
'cpa', // costModel
10, // cost
@@ -209,24 +209,24 @@
'12' // campaignId
);
- window.snowplow('trackAddToCart:cf', '000345', 'blue tie', 'clothing', 3.49, 2, 'GBP');
- window.snowplow('trackRemoveFromCart:cf', '000345', 'blue tie', 'clothing', 3.49, 1, 'GBP');
+ window.snowplow('trackAddToCart:sp', '000345', 'blue tie', 'clothing', 3.49, 2, 'GBP');
+ window.snowplow('trackRemoveFromCart:sp', '000345', 'blue tie', 'clothing', 3.49, 1, 'GBP');
- window.snowplow('trackSiteSearch:cf',
+ window.snowplow('trackSiteSearch:sp',
['unified', 'log'], // search terms
{'category': 'books', 'sub-category': 'non-fiction'}, // filters
14, // results found
8 // results displayed on first page
);
- window.snowplow('trackTiming:cf',
+ window.snowplow('trackTiming:sp',
'load', // Category of the timing variable
'map_loaded', // Variable being recorded
50, // Milliseconds taken
'Map loading time' // Optional label
);
- window.snowplow('trackConsentGranted:cf',
+ window.snowplow('trackConsentGranted:sp',
'1234', // Id
'5', // Version
'consent_document', // Name
@@ -234,7 +234,7 @@
'2020-11-21T08:00:00.000Z' // Expiry
);
- window.snowplow('trackConsentWithdrawn:cf',
+ window.snowplow('trackConsentWithdrawn:sp',
false, // All
'1234', // Id
'5', // Version
@@ -245,10 +245,10 @@
try {
notExistentObject.notExistentProperty();
} catch(e) {
- snowplow('trackError:cf', 'Cannot access notExistentProperty()', 'trackError.js', 237, 5, e);
+ snowplow('trackError:sp', 'Cannot access notExistentProperty()', 'trackError.js', 237, 5, e);
}
- window.snowplow('addEnhancedEcommerceActionContext:cf',
+ window.snowplow('addEnhancedEcommerceActionContext:sp',
'T12345', // The Transaction ID
'Google Store - Online', // The affiliate
'37.39', // The revenue
@@ -257,7 +257,7 @@
'WINTER2016' // The coupon
);
- window.snowplow('addEnhancedEcommerceImpressionContext:cf',
+ window.snowplow('addEnhancedEcommerceImpressionContext:sp',
'P12345', // The ID
'Android Warhol T-Shirt', // The name
'Search Results', // The list
@@ -267,7 +267,7 @@
'1' // The position
);
- window.snowplow('addEnhancedEcommerceProductContext:cf',
+ window.snowplow('addEnhancedEcommerceProductContext:sp',
'P12345', // The ID
'Android Warhol T-Shirt', // The name
'Search Results', // The list
@@ -277,19 +277,19 @@
1 // The quantity
);
- window.snowplow('addEnhancedEcommercePromoContext:cf',
+ window.snowplow('addEnhancedEcommercePromoContext:sp',
'PROMO_1234', // The Promotion ID
'Summer Sale', // The name
'summer_banner2', // The name of the creative
'banner_slot1' // The position
);
- window.snowplow('trackEnhancedEcommerceAction:cf',
+ window.snowplow('trackEnhancedEcommerceAction:sp',
'purchase'
);
// track unhandled exception
- window.snowplow('enableErrorTracking:cf', function (error) { return true; }, function (error) {
+ window.snowplow('enableErrorTracking:sp', function (error) { return true; }, function (error) {
return [
{
schema: "iglu:org.schema/WebPage/jsonschema/1-0-0",
diff --git a/tests/unit/in_queue.spec.js b/tests/unit/in_queue.spec.js
index 3e94c3ef2..c064782ef 100644
--- a/tests/unit/in_queue.spec.js
+++ b/tests/unit/in_queue.spec.js
@@ -90,15 +90,15 @@ describe('InQueueManager', () => {
})
it("Backward compatibility: Create a tracker using the legacy setCollectorUrl method, A second tracker is created and both trackers' attributes are added to output", () => {
- asyncQueue.push(['setCollectorUrl', 'secondEndpoint'])
+ asyncQueue.push(['newTracker', 'secondTracker', 'secondEndpoint'])
asyncQueue.push(['addAttributeToOutput'])
expect(output).toEqual(24)
})
it("Use 'function:tracker1;tracker2' syntax to control which trackers execute which functions, Set the attributes of the two trackers individually, then add both to output", () => {
asyncQueue.push(['setAttribute:firstTracker', 2])
- asyncQueue.push(['setAttribute:sp', 3])
- asyncQueue.push(['addAttributeToOutput:firstTracker;sp'])
+ asyncQueue.push(['setAttribute:secondTracker', 3])
+ asyncQueue.push(['addAttributeToOutput:firstTracker;secondTracker'])
expect(output).toEqual(29)
})
diff --git a/tests/unit/out_queue.spec.js b/tests/unit/out_queue.spec.js
index ccce68b00..39f1c70e4 100644
--- a/tests/unit/out_queue.spec.js
+++ b/tests/unit/out_queue.spec.js
@@ -44,7 +44,7 @@ describe('OutQueueManager', () => {
localStorage.clear();
outQueue = new OutQueueManager(
- 'sp', 'cf', {outQueues: []}, true, 'post',
+ 'sp', 'sp', {outQueues: []}, true, 'post',
'/com.snowplowanalytics.snowplow/tp2', 1, 40000, false,
maxQueueSize
);
@@ -54,7 +54,7 @@ describe('OutQueueManager', () => {
const expected = { e: "pv", eid: "20269f92-f07c-44a6-87ef-43e171305076" };
outQueue.enqueueRequest(expected, '');
- const retrievedQueue = JSON.parse(window.localStorage.getItem('snowplowOutQueue_sp_cf_post2'));
+ const retrievedQueue = JSON.parse(window.localStorage.getItem('snowplowOutQueue_sp_sp_post2'));
expect(retrievedQueue).toHaveLength(1);
expect(retrievedQueue[0]).toMatchObject({ bytes: 55, evt: expected });
})
@@ -68,7 +68,7 @@ describe('OutQueueManager', () => {
outQueue.enqueueRequest(expected2, '');
outQueue.enqueueRequest(unexpected, '');
- const retrievedQueue = JSON.parse(window.localStorage.getItem('snowplowOutQueue_sp_cf_post2'));
+ const retrievedQueue = JSON.parse(window.localStorage.getItem('snowplowOutQueue_sp_sp_post2'));
expect(retrievedQueue).toHaveLength(maxQueueSize);
expect(retrievedQueue[0]).toMatchObject({ bytes: 55, evt: expected1 });
expect(retrievedQueue[1]).toMatchObject({ bytes: 55, evt: expected2 });
diff --git a/tests/unit/proxies.spec.js b/tests/unit/proxies.spec.js
index a49cb33a9..1b0a91725 100644
--- a/tests/unit/proxies.spec.js
+++ b/tests/unit/proxies.spec.js
@@ -107,22 +107,4 @@ describe('Proxies', () => {
expect(fixedupLocationArray[i]).toEqual(expectedLocationArray[i])
}
})
-
- it('Host name is an IP address, On a page cached by Yahoo, get the original URL from the first link', () => {
- const initialLocationArray = [
- '98.139.21.31',
- 'http://98.139.21.31/search/srpcache',
- 'http://referrer.com',
- ]
- const fixedupLocationArray = fixupUrl.apply(null, initialLocationArray)
- const expectedLocationArray = [
- 'www.example.com',
- 'http://www.example.com/',
- 'http://referrer.com',
- ]
-
- for (let i = 0; i < 3; i++) {
- expect(fixedupLocationArray[i]).toEqual(expectedLocationArray[i])
- }
- })
})
From a1af2af229aae2e6afd362e8285970e21e41d695 Mon Sep 17 00:00:00 2001
From: Paul Boocock
Date: Wed, 9 Dec 2020 20:06:20 +0000
Subject: [PATCH 007/602] Add ES Module builds (close #882)
---
common/autoinstallers/rush-prettier/.npmrc | 22 ++
.../.rush/temp/last-install.flag | 14 ++
gulpfile.babel.js/build.js | 33 +++
gulpfile.babel.js/iife.js | 28 ---
gulpfile.babel.js/index.js | 12 +-
gulpfile.babel.js/rollup.js | 22 +-
gulpfile.babel.js/test.js | 10 +-
package-lock.json | 2 +-
package.json | 16 +-
src/js/{init.js => iife.js} | 15 +-
src/js/in_queue.js | 36 +---
src/js/shared_state.js | 171 ++++++++++++++++
src/js/snowplow.js | 193 ++++++------------
src/js/version.js | 3 +
tests/functional/cookies.spec.js | 2 +-
tests/integration/integration.spec.js | 7 +
tests/integration/sessionStorage.spec.js | 5 +-
tests/pages/activity-callback.html | 14 +-
tests/pages/cookies.html | 2 +-
tests/pages/integration.html | 31 ++-
tests/pages/session-integration.html | 27 ++-
tests/unit/in_queue.spec.js | 25 +--
22 files changed, 432 insertions(+), 258 deletions(-)
create mode 100644 common/autoinstallers/rush-prettier/.npmrc
create mode 100644 common/autoinstallers/rush-prettier/.rush/temp/last-install.flag
create mode 100644 gulpfile.babel.js/build.js
delete mode 100644 gulpfile.babel.js/iife.js
rename src/js/{init.js => iife.js} (86%)
create mode 100644 src/js/shared_state.js
create mode 100644 src/js/version.js
diff --git a/common/autoinstallers/rush-prettier/.npmrc b/common/autoinstallers/rush-prettier/.npmrc
new file mode 100644
index 000000000..b902e270c
--- /dev/null
+++ b/common/autoinstallers/rush-prettier/.npmrc
@@ -0,0 +1,22 @@
+# Rush uses this file to configure the NPM package registry during installation. It is applicable
+# to PNPM, NPM, and Yarn package managers. It is used by operations such as "rush install",
+# "rush update", and the "install-run.js" scripts.
+#
+# NOTE: The "rush publish" command uses .npmrc-publish instead.
+#
+# Before invoking the package manager, Rush will copy this file to the folder where installation
+# is performed. The copied file will omit any config lines that reference environment variables
+# that are undefined in that session; this avoids problems that would otherwise result due to
+# a missing variable being replaced by an empty string.
+#
+# * * * SECURITY WARNING * * *
+#
+# It is NOT recommended to store authentication tokens in a text file on a lab machine, because
+# other unrelated processes may be able to read the file. Also, the file may persist indefinitely,
+# for example if the machine loses power. A safer practice is to pass the token via an
+# environment variable, which can be referenced from .npmrc using ${} expansion. For example:
+#
+# //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}
+#
+registry=https://registry.npmjs.org/
+always-auth=false
diff --git a/common/autoinstallers/rush-prettier/.rush/temp/last-install.flag b/common/autoinstallers/rush-prettier/.rush/temp/last-install.flag
new file mode 100644
index 000000000..ef2a1358e
--- /dev/null
+++ b/common/autoinstallers/rush-prettier/.rush/temp/last-install.flag
@@ -0,0 +1,14 @@
+{
+ "node": "12.20.1",
+ "packageManager": "pnpm",
+ "packageManagerVersion": "4.14.4",
+ "packageJson": {
+ "name": "rush-prettier",
+ "version": "1.0.0",
+ "private": true,
+ "dependencies": {
+ "prettier": "^2.2.1",
+ "pretty-quick": "^3.1.0"
+ }
+ }
+}
diff --git a/gulpfile.babel.js/build.js b/gulpfile.babel.js/build.js
new file mode 100644
index 000000000..8345f0f55
--- /dev/null
+++ b/gulpfile.babel.js/build.js
@@ -0,0 +1,33 @@
+import { rollup } from 'rollup';
+import { core, licenseBanner, minify, sizeReport } from './rollup';
+
+export const iife = async function () {
+ const iife = await rollup({
+ input: 'src/js/iife.js',
+ plugins: [...core, ...minify, licenseBanner, ...sizeReport],
+ });
+
+ return await iife.write({
+ file: 'dist/sp.js',
+ format: 'iife',
+ });
+};
+
+const snowplow = rollup({
+ input: 'src/js/snowplow.js',
+ plugins: [...core, licenseBanner],
+});
+
+export const cjs = async function () {
+ return await (await snowplow).write({
+ file: 'dist/sp.cjs.js',
+ format: 'cjs',
+ });
+};
+
+export const esm = async function () {
+ return await (await snowplow).write({
+ file: 'dist/sp.esm.js',
+ format: 'es',
+ });
+};
diff --git a/gulpfile.babel.js/iife.js b/gulpfile.babel.js/iife.js
deleted file mode 100644
index 8a231dbf3..000000000
--- a/gulpfile.babel.js/iife.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { rollup } from 'rollup';
-import compiler from '@ampproject/rollup-plugin-closure-compiler';
-import cleanup from 'rollup-plugin-cleanup';
-import sizes from 'rollup-plugin-sizes';
-import filesize from 'rollup-plugin-filesize';
-import { basePlugins, spBannerPlugin } from './rollup';
-
-const minify = [
- compiler(),
- cleanup({comments: 'none'})
-]
-
-const report = [
- sizes(),
- filesize({showMinifiedSize: false, showBeforeSizes: 'build'})
-]
-
-export const buildSp = async function () {
- const snowplow = await rollup({
- input: 'src/js/init.js',
- plugins: [...basePlugins, ...minify, spBannerPlugin, ...report],
- });
-
- return await snowplow.write({
- file: 'dist/sp.js',
- format: 'iife',
- });
-};
diff --git a/gulpfile.babel.js/index.js b/gulpfile.babel.js/index.js
index 60c00803a..ee83d6f50 100644
--- a/gulpfile.babel.js/index.js
+++ b/gulpfile.babel.js/index.js
@@ -1,8 +1,12 @@
import { parallel } from 'gulp';
-import { buildSp } from './iife';
+import { iife, esm, cjs } from './build';
import { pullSnowplowMicro, buildTestDetectors, buildTestHelpers, buildTestSnowplow } from './test';
-export const build = buildSp;
-export const testEndToEnd = parallel(pullSnowplowMicro, buildTestDetectors, buildTestHelpers, buildTestSnowplow);
+export const buildIife = iife;
+export const buildEsm = esm;
+export const buildCjs = cjs;
-export default buildSp;
+export const build = parallel(iife, esm, cjs);
+export const buildForIntegrationTest = parallel(pullSnowplowMicro, buildTestDetectors, buildTestHelpers, buildTestSnowplow);
+
+export default build;
diff --git a/gulpfile.babel.js/rollup.js b/gulpfile.babel.js/rollup.js
index 91577c36b..68aa2d0e7 100644
--- a/gulpfile.babel.js/rollup.js
+++ b/gulpfile.babel.js/rollup.js
@@ -1,10 +1,24 @@
import { nodeResolve } from '@rollup/plugin-node-resolve';
-import commonjs from '@rollup/plugin-commonjs';
import { babel } from '@rollup/plugin-babel';
+import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import banner from 'rollup-plugin-banner'
+import compiler from '@ampproject/rollup-plugin-closure-compiler';
+import cleanup from 'rollup-plugin-cleanup';
+import sizes from 'rollup-plugin-sizes';
+import filesize from 'rollup-plugin-filesize';
+
+export const sizeReport = [
+ sizes(),
+ filesize({showMinifiedSize: false, showBeforeSizes: 'build'})
+]
+
+export const minify = [
+ compiler(),
+ cleanup({comments: 'none'})
+]
-export const basePlugins = [
+export const core = [
json(),
nodeResolve({
browser: true,
@@ -31,11 +45,11 @@ export const basePlugins = [
})
];
-const licenseBanner =
+const bannerContent =
"@description <%= pkg.description %>\n" +
"@version <%= pkg.version %>\n" +
"@copyright Anthon Pang, Snowplow Analytics Ltd\n" +
"@license <%= pkg.license %>\n\n" +
"Documentation: http://bit.ly/sp-js";
-export const spBannerPlugin = banner(licenseBanner);
+export const licenseBanner = banner(bannerContent);
diff --git a/gulpfile.babel.js/test.js b/gulpfile.babel.js/test.js
index 97d7e4d8c..2891b6cb6 100644
--- a/gulpfile.babel.js/test.js
+++ b/gulpfile.babel.js/test.js
@@ -1,11 +1,11 @@
import { rollup } from 'rollup';
-import { basePlugins } from './rollup';
+import { core } from './rollup';
import Docker from 'dockerode';
export const buildTestDetectors = async function () {
const detectors = await rollup({
input: 'tests/scripts/detectors.js',
- plugins: basePlugins,
+ plugins: core,
});
return await detectors.write({
name: 'detectors',
@@ -17,7 +17,7 @@ export const buildTestDetectors = async function () {
export const buildTestHelpers = async function () {
const helpers = await rollup({
input: 'tests/scripts/helpers.js',
- plugins: basePlugins,
+ plugins: core,
});
return await helpers.write({
name: 'helpers',
@@ -28,8 +28,8 @@ export const buildTestHelpers = async function () {
export const buildTestSnowplow = async function () {
const snowplow = await rollup({
- input: 'src/js/init.js',
- plugins: basePlugins,
+ input: 'src/js/iife.js',
+ plugins: core,
});
return await snowplow.write({
diff --git a/package-lock.json b/package-lock.json
index 5ae64454a..9c4ea7e2e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,5 +1,5 @@
{
- "name": "snowplow-tracker",
+ "name": "@snowplow/browser-tracker",
"version": "2.17.3",
"lockfileVersion": 1,
"requires": true,
diff --git a/package.json b/package.json
index 2860cae7c..2fbc165b9 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,20 @@
{
- "name": "snowplow-tracker",
+ "name": "@snowplow/browser-tracker",
"version": "2.17.3",
+ "main": "dist/sp.cjs.js",
+ "module": "dist/sp.esm.js",
+ "jsnext:main": "dist/sp.esm.js",
+ "unpkg": "dist/sp.js",
+ "jsdelivr": "dist/sp.js",
+ "files": [
+ "dist"
+ ],
"scripts": {
- "build": "gulp build",
+ "build": "gulp",
"build:all": "(cd core && npm run build) && npm run build",
"test:unit": "jest tests/unit/*.spec.js",
- "test:e2e:sauce": "gulp testEndToEnd && wdio tests/wdio.sauce.conf.js",
- "test:e2e:local": "gulp testEndToEnd && wdio tests/wdio.local.conf.js"
+ "test:e2e:sauce": "gulp buildForIntegrationTest && wdio tests/wdio.sauce.conf.js",
+ "test:e2e:local": "gulp buildForIntegrationTest && wdio tests/wdio.local.conf.js"
},
"dependencies": {
"jstimezonedetect": "1.0.5",
diff --git a/src/js/init.js b/src/js/iife.js
similarity index 86%
rename from src/js/init.js
rename to src/js/iife.js
index bcc369fff..d7de3445b 100644
--- a/src/js/init.js
+++ b/src/js/iife.js
@@ -38,12 +38,11 @@
* Get the name of the global input function
*/
-import { Snowplow } from './snowplow';
+import { InQueueManager } from './in_queue';
+
+const windowAlias = window,
+ functionName = windowAlias.GlobalSnowplowNamespace.shift(),
+ queue = windowAlias[functionName];
-var queueName,
- queue,
- windowAlias = window;
-
-queueName = windowAlias.GlobalSnowplowNamespace.shift();
-queue = windowAlias[queueName];
-queue.q = new Snowplow(queue.q, queueName);
+// Now replace initialization array with queue manager object
+queue.q = new InQueueManager(functionName, queue.q);
diff --git a/src/js/in_queue.js b/src/js/in_queue.js
index 1ecc10d16..34bf18ace 100644
--- a/src/js/in_queue.js
+++ b/src/js/in_queue.js
@@ -33,8 +33,8 @@
*/
import map from 'lodash/map';
-import isUndefined from 'lodash/isUndefined';
import { warn, isFunction } from './lib/helpers';
+import { newTracker, getTracker, allTrackers } from './snowplow'
/************************************************************
* Proxy object
@@ -42,10 +42,7 @@ import { warn, isFunction } from './lib/helpers';
* after the Tracker has been initialized and loaded
************************************************************/
-export function InQueueManager(TrackerConstructor, version, mutSnowplowState, asyncQueue, functionName) {
- // Page view ID should be shared between all tracker instances
- var trackerDictionary = {};
-
+export function InQueueManager(functionName, asyncQueue) {
/**
* Get an array of trackers to which a function should be applied.
*
@@ -55,14 +52,10 @@ export function InQueueManager(TrackerConstructor, version, mutSnowplowState, as
var namedTrackers = [];
if (!names || names.length === 0) {
- namedTrackers = map(trackerDictionary);
+ namedTrackers = map(allTrackers(functionName));
} else {
for (var i = 0; i < names.length; i++) {
- if (trackerDictionary.hasOwnProperty(names[i])) {
- namedTrackers.push(trackerDictionary[names[i]]);
- } else {
- warn('Warning: Tracker namespace "' + names[i] + '" not configured');
- }
+ namedTrackers.push(getTracker(names[i], functionName));
}
}
@@ -73,23 +66,6 @@ export function InQueueManager(TrackerConstructor, version, mutSnowplowState, as
return namedTrackers;
}
- /**
- * Initiate a new tracker namespace
- *
- * @param string namespace
- * @param string endpoint Of the form d3rkrsqld9gmqf.cloudfront.net
- */
- function createNewNamespace(namespace, endpoint, argmap) {
- argmap = argmap || {};
-
- if (!trackerDictionary.hasOwnProperty(namespace)) {
- trackerDictionary[namespace] = new TrackerConstructor(functionName, namespace, version, mutSnowplowState, argmap);
- trackerDictionary[namespace].setCollectorUrl(endpoint);
- } else {
- warn('Tracker namespace ' + namespace + ' already exists.');
- }
- }
-
/**
* Output an array of the form ['functionName', [trackerName1, trackerName2, ...]]
*
@@ -124,7 +100,7 @@ export function InQueueManager(TrackerConstructor, version, mutSnowplowState, as
// Custom callback rather than tracker method, called with trackerDictionary as the context
if (isFunction(input)) {
try {
- input.apply(trackerDictionary, parameterArray);
+ input.apply(allTrackers(functionName), parameterArray);
} catch (e) {
warn(`Custom callback error - ${e}`);
} finally {
@@ -137,7 +113,7 @@ export function InQueueManager(TrackerConstructor, version, mutSnowplowState, as
names = parsedString[1];
if (f === 'newTracker') {
- createNewNamespace(parameterArray[0], parameterArray[1], parameterArray[2]);
+ newTracker(parameterArray[0], parameterArray[1], parameterArray[2], functionName);
continue;
}
diff --git a/src/js/shared_state.js b/src/js/shared_state.js
new file mode 100644
index 000000000..b87fec648
--- /dev/null
+++ b/src/js/shared_state.js
@@ -0,0 +1,171 @@
+/*
+ * JavaScript tracker for Snowplow: snowplow.js
+ *
+ * Significant portions copyright 2010 Anthon Pang. Remainder copyright
+ * 2012-2020 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.
+ */
+
+import forEach from 'lodash/forEach';
+import { addEventListener } from './lib/helpers';
+
+export function SharedState() {
+ var documentAlias = document,
+ windowAlias = window,
+ /* Contains four variables that are shared with tracker.js and must be passed by reference */
+ mutSnowplowState = {
+ /* List of request queues - one per Tracker instance */
+ outQueues: [],
+ bufferFlushers: [],
+
+ /* Time at which to stop blocking excecution */
+ expireDateTime: null,
+
+ /* DOM Ready */
+ hasLoaded: false,
+ registeredOnLoadHandlers: [],
+
+ /* pageViewId, which can changed by other trackers on page;
+ * initialized by tracker sent first event */
+ pageViewId: null,
+ };
+
+ /************************************************************
+ * Private methods
+ ************************************************************/
+
+ /*
+ * Handle beforeunload event
+ *
+ * Subject to Safari's "Runaway JavaScript Timer" and
+ * Chrome V8 extension that terminates JS that exhibits
+ * "slow unload", i.e., calling getTime() > 1000 times
+ */
+ function beforeUnloadHandler() {
+ var now;
+
+ // Flush all POST queues
+ forEach(mutSnowplowState.bufferFlushers, function (flusher) {
+ flusher();
+ });
+
+ /*
+ * Delay/pause (blocks UI)
+ */
+ if (mutSnowplowState.expireDateTime) {
+ // the things we do for backwards compatibility...
+ // in ECMA-262 5th ed., we could simply use:
+ // while (Date.now() < mutSnowplowState.expireDateTime) { }
+ do {
+ now = new Date();
+ if (
+ Array.prototype.filter.call(mutSnowplowState.outQueues, function (queue) {
+ return queue.length > 0;
+ }).length === 0
+ ) {
+ break;
+ }
+ } while (now.getTime() < mutSnowplowState.expireDateTime);
+ }
+ }
+
+ /*
+ * Handler for onload event
+ */
+ function loadHandler() {
+ var i;
+
+ if (!mutSnowplowState.hasLoaded) {
+ mutSnowplowState.hasLoaded = true;
+ for (i = 0; i < mutSnowplowState.registeredOnLoadHandlers.length; i++) {
+ mutSnowplowState.registeredOnLoadHandlers[i]();
+ }
+ }
+ return true;
+ }
+
+ /*
+ * Add onload or DOM ready handler
+ */
+ function addReadyListener() {
+ var _timer;
+
+ if (documentAlias.addEventListener) {
+ addEventListener(documentAlias, 'DOMContentLoaded', function ready() {
+ documentAlias.removeEventListener('DOMContentLoaded', ready, false);
+ loadHandler();
+ });
+ } else if (documentAlias.attachEvent) {
+ documentAlias.attachEvent('onreadystatechange', function ready() {
+ if (documentAlias.readyState === 'complete') {
+ documentAlias.detachEvent('onreadystatechange', ready);
+ loadHandler();
+ }
+ });
+
+ if (documentAlias.documentElement.doScroll && windowAlias === windowAlias.top) {
+ (function ready() {
+ if (!mutSnowplowState.hasLoaded) {
+ try {
+ documentAlias.documentElement.doScroll('left');
+ } catch (error) {
+ setTimeout(ready, 0);
+ return;
+ }
+ loadHandler();
+ }
+ })();
+ }
+ }
+
+ // sniff for older WebKit versions
+ if (new RegExp('WebKit').test(navigator.userAgent)) {
+ _timer = setInterval(function () {
+ if (mutSnowplowState.hasLoaded || /loaded|complete/.test(documentAlias.readyState)) {
+ clearInterval(_timer);
+ loadHandler();
+ }
+ }, 10);
+ }
+
+ // fallback
+ addEventListener(windowAlias, 'load', loadHandler, false);
+ }
+
+ /************************************************************
+ * Constructor
+ ************************************************************/
+
+ // initialize the Snowplow singleton
+ addEventListener(windowAlias, 'beforeunload', beforeUnloadHandler, false);
+ addReadyListener();
+
+
+ return mutSnowplowState
+}
diff --git a/src/js/snowplow.js b/src/js/snowplow.js
index c0b2bc496..1a9ba2916 100644
--- a/src/js/snowplow.js
+++ b/src/js/snowplow.js
@@ -1,5 +1,7 @@
+Ddd;
+
/*
- * JavaScript tracker for Snowplow: snowplow.js
+ * JavaScript tracker for Snowplow: init.js
*
* Significant portions copyright 2010 Anthon Pang. Remainder copyright
* 2012-2020 Snowplow Analytics Ltd. All rights reserved.
@@ -9,15 +11,15 @@
* met:
*
* * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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.
+ * 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.
+ * 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
@@ -32,145 +34,72 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import forEach from 'lodash/forEach';
-import { addEventListener } from './lib/helpers';
-import { InQueueManager } from './in_queue';
-import { Tracker } from './tracker';
-import { version as jsVersion } from '../../package.json'
-
-export function Snowplow(asynchronousQueue, functionName) {
- var documentAlias = document,
- windowAlias = window,
- /* Tracker identifier with version */
- version = 'js-' + jsVersion,
- /* Contains four variables that are shared with tracker.js and must be passed by reference */
- mutSnowplowState = {
- /* List of request queues - one per Tracker instance */
- outQueues: [],
- bufferFlushers: [],
-
- /* Time at which to stop blocking excecution */
- expireDateTime: null,
+// Snowplow Asynchronous Queue
- /* DOM Ready */
- hasLoaded: false,
- registeredOnLoadHandlers: [],
-
- /* pageViewId, which can changed by other trackers on page;
- * initialized by tracker sent first event */
- pageViewId: null,
- };
-
- /************************************************************
- * Private methods
- ************************************************************/
+/*
+ * Get the name of the global input function
+ */
- /*
- * Handle beforeunload event
- *
- * Subject to Safari's "Runaway JavaScript Timer" and
- * Chrome V8 extension that terminates JS that exhibits
- * "slow unload", i.e., calling getTime() > 1000 times
- */
- function beforeUnloadHandler() {
- var now;
+import { Tracker } from './tracker';
+import { SharedState } from './shared_state';
+import { version } from './version';
+import { warn } from './lib/helpers';
+import pickBy from 'lodash/pickBy';
+import includes from 'lodash/includes';
- // Flush all POST queues
- forEach(mutSnowplowState.bufferFlushers, function (flusher) {
- flusher();
- });
+const groups = {};
- /*
- * Delay/pause (blocks UI)
- */
- if (mutSnowplowState.expireDateTime) {
- // the things we do for backwards compatibility...
- // in ECMA-262 5th ed., we could simply use:
- // while (Date.now() < mutSnowplowState.expireDateTime) { }
- do {
- now = new Date();
- if (
- Array.prototype.filter.call(mutSnowplowState.outQueues, function (queue) {
- return queue.length > 0;
- }).length === 0
- ) {
- break;
- }
- } while (now.getTime() < mutSnowplowState.expireDateTime);
- }
+/**
+ * Initiate a new tracker
+ *
+ * @param string name
+ * @param string endpoint in the form collector.mysite.com
+ * @param object argmap contains the initialisation options of the JavaScript tracker
+ * @param string trackerGroup used to group multiple trackers and shared state together
+ */
+export const newTracker = (name, endpoint, argmap = {}, trackerGroup = 'snowplow') => {
+ if (!groups.hasOwnProperty(trackerGroup)) {
+ groups[trackerGroup] = { state: new SharedState(), trackers: {} };
}
- /*
- * Handler for onload event
- */
- function loadHandler() {
- var i;
+ const trackerDictionary = groups[trackerGroup].trackers;
+ const state = groups[trackerGroup].state;
- if (!mutSnowplowState.hasLoaded) {
- mutSnowplowState.hasLoaded = true;
- for (i = 0; i < mutSnowplowState.registeredOnLoadHandlers.length; i++) {
- mutSnowplowState.registeredOnLoadHandlers[i]();
- }
- }
- return true;
+ if (!trackerDictionary.hasOwnProperty(name)) {
+ trackerDictionary[name] = new Tracker(trackerGroup, name, version, state, argmap);
+ trackerDictionary[name].setCollectorUrl(endpoint);
+ } else {
+ warn('Tracker namespace ' + name + ' already exists.');
}
- /*
- * Add onload or DOM ready handler
- */
- function addReadyListener() {
- var _timer;
+ return trackerDictionary[name];
+};
- if (documentAlias.addEventListener) {
- addEventListener(documentAlias, 'DOMContentLoaded', function ready() {
- documentAlias.removeEventListener('DOMContentLoaded', ready, false);
- loadHandler();
- });
- } else if (documentAlias.attachEvent) {
- documentAlias.attachEvent('onreadystatechange', function ready() {
- if (documentAlias.readyState === 'complete') {
- documentAlias.detachEvent('onreadystatechange', ready);
- loadHandler();
- }
- });
-
- if (documentAlias.documentElement.doScroll && windowAlias === windowAlias.top) {
- (function ready() {
- if (!mutSnowplowState.hasLoaded) {
- try {
- documentAlias.documentElement.doScroll('left');
- } catch (error) {
- setTimeout(ready, 0);
- return;
- }
- loadHandler();
- }
- })();
- }
- }
+export const getTracker = (namespace, trackerGroup = 'snowplow') => {
+ if (groups.hasOwnProperty(trackerGroup) && groups[trackerGroup].trackers.hasOwnProperty(namespace)) {
+ return groups[trackerGroup].trackers[namespace];
+ }
- // sniff for older WebKit versions
- if (new RegExp('WebKit').test(navigator.userAgent)) {
- _timer = setInterval(function () {
- if (mutSnowplowState.hasLoaded || /loaded|complete/.test(documentAlias.readyState)) {
- clearInterval(_timer);
- loadHandler();
- }
- }, 10);
- }
+ warn('Warning: No tracker configured');
+ return null;
+};
- // fallback
- addEventListener(windowAlias, 'load', loadHandler, false);
+export const getTrackers = (namespaces, trackerGroup = 'snowplow') => {
+ if (groups.hasOwnProperty(trackerGroup)) {
+ return pickBy(groups[trackerGroup].trackers, (_, key) => {
+ return includes(namespaces, key);
+ });
}
- /************************************************************
- * Constructor
- ************************************************************/
+ warn('Warning: No trackers configured');
+ return {};
+};
- // initialize the Snowplow singleton
- addEventListener(windowAlias, 'beforeunload', beforeUnloadHandler, false);
- addReadyListener();
+export const allTrackers = (trackerGroup = 'snowplow') => {
+ if (groups.hasOwnProperty(trackerGroup)) {
+ return groups[trackerGroup].trackers;
+ }
- // Now replace initialization array with queue manager object
- return new InQueueManager(Tracker, version, mutSnowplowState, asynchronousQueue, functionName);
-}
+ warn('Warning: No trackers configured');
+ return {};
+};
diff --git a/src/js/version.js b/src/js/version.js
new file mode 100644
index 000000000..0883ed49a
--- /dev/null
+++ b/src/js/version.js
@@ -0,0 +1,3 @@
+import { version as jsVersion } from '../../package.json'
+
+export const version = 'js-' + jsVersion;
\ No newline at end of file
diff --git a/tests/functional/cookies.spec.js b/tests/functional/cookies.spec.js
index 78a6bdd08..f7ff672a7 100644
--- a/tests/functional/cookies.spec.js
+++ b/tests/functional/cookies.spec.js
@@ -57,7 +57,7 @@ describe('Tracker created domain cookies', () => {
expect(cookies).not.toContain('_sp_0ses.'); // Missing as tests are not HTTPS and `cookieSecure: true` by default
expect(cookies).not.toContain('_sp_0id.');
- expect(cookies).not.toContain('_sp_3es.'); // Missing as cookie lifetime is too short (1)
+ expect(cookies).not.toContain('_sp_3ses.'); // Missing as cookie lifetime is too short (1)
expect(cookies).not.toContain('_sp_3id.');
expect(cookies).not.toContain('_sp_4ses.'); // Missing as anonymous tracking enabled
expect(cookies).not.toContain('_sp_4id.');
diff --git a/tests/integration/integration.spec.js b/tests/integration/integration.spec.js
index 041b47362..c99d7204d 100755
--- a/tests/integration/integration.spec.js
+++ b/tests/integration/integration.spec.js
@@ -54,6 +54,13 @@ const loadUrlAndWait = (url) => {
timeoutMsg: 'expected init after 5s'
}
)
+ browser.waitUntil(
+ () => $('#secondInit').getText() === 'true',
+ {
+ timeout: 5000,
+ timeoutMsg: 'expected init after 5s'
+ }
+ )
}
const isMatchWithCallback = F.isMatchWith((lt, rt) =>
diff --git a/tests/integration/sessionStorage.spec.js b/tests/integration/sessionStorage.spec.js
index b1ec559c3..63883acc6 100644
--- a/tests/integration/sessionStorage.spec.js
+++ b/tests/integration/sessionStorage.spec.js
@@ -53,7 +53,7 @@ describe('Sessions', () => {
browser.url('/index.html')
browser.setCookies({ name: 'container', value: docker.url })
browser.url('/session-integration.html')
- browser.pause(5000) // Time for requests to get written
+ browser.pause(6000) // Time for requests to get written
browser.call(() =>
fetchResults(docker.url).then(result => {
log = result
@@ -109,6 +109,7 @@ describe('Sessions', () => {
F.get('event.domain_sessionidx', ev) === 1
expect(F.size(F.filter(withSingleVid, log))).toBe(2)
+ expect(F.size(F.filter(e => F.get('event.name_tracker', e) === 'localStorageSessionTracker', log))).toBe(3)
})
it('should only increment domain_sessionidx outside of session timeout (anonymous session tracking)', () => {
@@ -117,6 +118,7 @@ describe('Sessions', () => {
F.get('event.domain_sessionidx', ev) === 1
expect(F.size(F.filter(withSingleVid, log))).toBe(2)
+ expect(F.size(F.filter(e => F.get('event.name_tracker', e) === 'anonymousSessionTracker', log))).toBe(3)
})
it('should only increment domain_sessionidx outside of session timeout (cookie storage)', () => {
@@ -125,5 +127,6 @@ describe('Sessions', () => {
F.get('event.domain_sessionidx', ev) === 1
expect(F.size(F.filter(withSingleVid, log))).toBe(2)
+ expect(F.size(F.filter(e => F.get('event.name_tracker', e) === 'cookieSessionTracker', log))).toBe(3)
})
})
diff --git a/tests/pages/activity-callback.html b/tests/pages/activity-callback.html
index 93d297c28..44f32dea6 100644
--- a/tests/pages/activity-callback.html
+++ b/tests/pages/activity-callback.html
@@ -12,16 +12,16 @@
;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[];
p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments)
};p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1;
- n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","./snowplow.js","snowplow"));
+ n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","./snowplow.js","spActivity"));
- snowplow('newTracker', 'sp', 'snowplow-js-tracker.local:9090');
- snowplow(function() {
+ spActivity('newTracker', 'sp', 'snowplow-js-tracker.local:9090');
+ spActivity(function() {
document.getElementById('init').innerText = 'true';
});
var events = [];
- snowplow('enableActivityTrackingCallback', 2, 2, function(e) {
+ spActivity('enableActivityTrackingCallback', 2, 2, function(e) {
events.push(e);
document.getElementById('numEvents').innerText = events.length;
});
@@ -63,15 +63,15 @@
}
function trackPageView() {
- snowplow('trackPageView');
+ spActivity('trackPageView');
}
function getCurrentPageViewId(cb) {
- snowplow(function() {
+ spActivity(function() {
cb(this.sp.getPageViewId())
});
}
- snowplow('trackPageView')
+ spActivity('trackPageView')