jsinovassin commented on code in PR #4:
URL: https://github.com/apache/unomi-tracker/pull/4#discussion_r966819860
##########
dist/apache-unomi-tracker.cjs.js:
##########
@@ -0,0 +1,1571 @@
+'use strict';
Review Comment:
Why having cjs, esm, umd files instead of only one minified file?
##########
dist/apache-unomi-tracker.cjs.js:
##########
@@ -0,0 +1,1571 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+var _typeof = require('@babel/runtime/helpers/typeof');
+var es6CrawlerDetect = require('es6-crawler-detect');
+
+function _interopDefaultLegacy (e) { return e && typeof e === 'object' &&
'default' in e ? e : { 'default': e }; }
+
+var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof);
+
+function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof
Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if
(Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike &&
o && typeof o.length === "number") { if (it) o = it; var i = 0; var F =
function F() {}; return { s: F, n: function n() { if (i >= o.length) return {
done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) {
throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate
non-iterable instance.\nIn order to be iterable, non-array objects must have a
[Symbol.iterator]() method."); } var normalCompletion = true, didErr = false,
err; return { s: function s() { it = it.call(o); }, n: function n() { var step
= it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) {
didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion &&
it.return != null) it.return(); } finally { if (didErr) throw err; } } };
}
+
+function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o
=== "string") return _arrayLikeToArray(o, minLen); var n =
Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" &&
o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return
Array.from(o); if (n === "Arguments" ||
/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o,
minLen); }
+
+function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length)
len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) {
arr2[i] = arr[i]; } return arr2; }
+var newTracker = function newTracker() {
+ var wem = {
+ /**
+ * This function initialize the tracker
+ *
+ * @param {object} digitalData config of the tracker
+ * @returns {undefined}
+ */
+ initTracker: function initTracker(digitalData) {
+ wem.digitalData = digitalData;
+ wem.trackerProfileIdCookieName =
wem.digitalData.wemInitConfig.trackerProfileIdCookieName ?
wem.digitalData.wemInitConfig.trackerProfileIdCookieName : 'wem-profile-id';
+ wem.trackerSessionIdCookieName =
wem.digitalData.wemInitConfig.trackerSessionIdCookieName ?
wem.digitalData.wemInitConfig.trackerSessionIdCookieName : 'wem-session-id';
+ wem.browserGeneratedSessionSuffix =
wem.digitalData.wemInitConfig.browserGeneratedSessionSuffix ?
wem.digitalData.wemInitConfig.browserGeneratedSessionSuffix : '';
+ wem.disableTrackedConditionsListeners =
wem.digitalData.wemInitConfig.disableTrackedConditionsListeners;
+ wem.activateWem = wem.digitalData.wemInitConfig.activateWem;
+ var _wem$digitalData$wemI = wem.digitalData.wemInitConfig,
+ contextServerUrl = _wem$digitalData$wemI.contextServerUrl,
+ timeoutInMilliseconds = _wem$digitalData$wemI.timeoutInMilliseconds,
+ contextServerCookieName =
_wem$digitalData$wemI.contextServerCookieName;
+ wem.contextServerCookieName = contextServerCookieName;
+ wem.contextServerUrl = contextServerUrl;
+ wem.timeoutInMilliseconds = timeoutInMilliseconds;
+ wem.formNamesToWatch = [];
+ wem.eventsPrevented = [];
+ wem.sessionID = wem.getCookie(wem.trackerSessionIdCookieName);
+ wem.fallback = false;
+
+ if (wem.sessionID === null) {
+ console.warn('[WEM] sessionID is null !');
+ } else if (!wem.sessionID || wem.sessionID === '') {
+ console.warn('[WEM] empty sessionID, setting to null !');
+ wem.sessionID = null;
+ }
+ },
+
+ /**
+ * This function start the tracker by loading the context in the page
+ * Note: that the tracker will start once the current DOM is complete
loaded, using listener on current document: DOMContentLoaded
+ *
+ * @param {object[]} digitalDataOverrides optional, list of digitalData
extensions, they will be merged with original digitalData before context loading
+ * @returns {undefined}
+ */
+ startTracker: function startTracker() {
+ var digitalDataOverrides = arguments.length > 0 && arguments[0] !==
undefined ? arguments[0] : undefined;
+ // Check before start
+ var cookieDisabled = !navigator.cookieEnabled;
+ var noSessionID = !wem.sessionID || wem.sessionID === '';
+ var crawlerDetected = navigator.userAgent;
+
+ if (crawlerDetected) {
+ var browserDetector = new es6CrawlerDetect.Crawler();
+ crawlerDetected = browserDetector.isCrawler(navigator.userAgent);
+ }
+
+ if (cookieDisabled || noSessionID || crawlerDetected) {
+ document.addEventListener('DOMContentLoaded', function () {
+ wem._executeFallback('navigator cookie disabled: ' + cookieDisabled
+ ', no sessionID: ' + noSessionID + ', web crawler detected: ' +
crawlerDetected);
+ });
+ return;
+ } // Register base context callback
+
+
+ wem._registerCallback(function () {
+ if (wem.cxs.profileId) {
+ wem.setCookie(wem.trackerProfileIdCookieName, wem.cxs.profileId);
+ }
+
+ if (!wem.cxs.profileId) {
+ wem.removeCookie(wem.trackerProfileIdCookieName);
+ }
+
+ if (!wem.disableTrackedConditionsListeners) {
+ wem._registerListenersForTrackedConditions();
+ }
+ }, 'Default tracker', 0); // Load the context once document is ready
+
+
+ document.addEventListener('DOMContentLoaded', function () {
+ wem.DOMLoaded = true; // enrich digital data considering extensions
+
+ wem._handleDigitalDataOverrides(digitalDataOverrides); // complete
already registered events
+
+
+ wem._checkUncompleteRegisteredEvents(); // Dispatch javascript events
for the experience (perso/opti displayed from SSR, based on unomi events)
+
+
+ wem._dispatchJSExperienceDisplayedEvents(); // Some event may not need
to be send to unomi, check for them and filter them out.
+
+
+ wem._filterUnomiEvents(); // Add referrer info into digitalData.page
object.
+
+
+ wem._processReferrer(); // Build view event
+
+
+ var viewEvent = wem.buildEvent('view', wem.buildTargetPage(),
wem.buildSource(wem.digitalData.site.siteInfo.siteID, 'site'));
+ viewEvent.flattenedProperties = {}; // Add URLParameters
+
+ if (location.search) {
+ viewEvent.flattenedProperties['URLParameters'] =
wem.convertUrlParametersToObj(location.search);
+ } // Add interests
+
+
+ if (wem.digitalData.interests) {
+ viewEvent.flattenedProperties['interests'] =
wem.digitalData.interests;
+ } // Register the page view event, it's unshift because it should be
the first event, this is just for logical purpose. (page view comes before
perso displayed event for example)
+
+
+ wem._registerEvent(viewEvent, true);
+
+ if (wem.activateWem) {
+ wem.loadContext();
+ } else {
+ wem._executeFallback('wem is not activated on current page');
+ }
+ });
+ },
+
+ /**
+ * get the current loaded context from Unomi, will be accessible only
after loadContext() have been performed
+ * @returns {object} loaded context
+ */
+ getLoadedContext: function getLoadedContext() {
+ return wem.cxs;
+ },
+
+ /**
+ * In case Unomi contains rules related to HTML forms in the current page.
+ * The logic is simple, in case a rule exists in Unomi targeting a form
event within the current webpage path
+ * - then this form will be identified as form to be watched.
+ * You can reuse this function to get the list of concerned forms in order
to attach listeners automatically for those form for example
+ * (not that current tracker is doing that by default, check function:
_registerListenersForTrackedConditions())
+ * @returns {string[]} form names/ids in current web page
+ */
+ getFormNamesToWatch: function getFormNamesToWatch() {
+ return wem.formNamesToWatch;
+ },
+
+ /**
+ * Get current session id
+ * @returns {null|string} get current session id
+ */
+ getSessionId: function getSessionId() {
+ return wem.sessionID;
+ },
+
+ /**
+ * This function will register a personalization
+ *
+ * @param {object} personalization the personalization object
+ * @param {object} variants the variants
+ * @param {boolean} [ajax] Deprecated: Ajax rendering is not supported
anymore
+ * @param {function} [resultCallback] the callback to be executed after
personalization resolved
+ * @returns {undefined}
+ */
+ registerPersonalizationObject: function
registerPersonalizationObject(personalization, variants, ajax, resultCallback) {
Review Comment:
Can we simply remove the ajax parameter? because it's not used
##########
dist/apache-unomi-tracker.cjs.js:
##########
@@ -0,0 +1,1571 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+var _typeof = require('@babel/runtime/helpers/typeof');
+var es6CrawlerDetect = require('es6-crawler-detect');
+
+function _interopDefaultLegacy (e) { return e && typeof e === 'object' &&
'default' in e ? e : { 'default': e }; }
+
+var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof);
+
+function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof
Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if
(Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike &&
o && typeof o.length === "number") { if (it) o = it; var i = 0; var F =
function F() {}; return { s: F, n: function n() { if (i >= o.length) return {
done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) {
throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate
non-iterable instance.\nIn order to be iterable, non-array objects must have a
[Symbol.iterator]() method."); } var normalCompletion = true, didErr = false,
err; return { s: function s() { it = it.call(o); }, n: function n() { var step
= it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) {
didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion &&
it.return != null) it.return(); } finally { if (didErr) throw err; } } };
}
+
+function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o
=== "string") return _arrayLikeToArray(o, minLen); var n =
Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" &&
o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return
Array.from(o); if (n === "Arguments" ||
/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o,
minLen); }
+
+function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length)
len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) {
arr2[i] = arr[i]; } return arr2; }
+var newTracker = function newTracker() {
+ var wem = {
+ /**
+ * This function initialize the tracker
+ *
+ * @param {object} digitalData config of the tracker
+ * @returns {undefined}
+ */
+ initTracker: function initTracker(digitalData) {
+ wem.digitalData = digitalData;
+ wem.trackerProfileIdCookieName =
wem.digitalData.wemInitConfig.trackerProfileIdCookieName ?
wem.digitalData.wemInitConfig.trackerProfileIdCookieName : 'wem-profile-id';
+ wem.trackerSessionIdCookieName =
wem.digitalData.wemInitConfig.trackerSessionIdCookieName ?
wem.digitalData.wemInitConfig.trackerSessionIdCookieName : 'wem-session-id';
+ wem.browserGeneratedSessionSuffix =
wem.digitalData.wemInitConfig.browserGeneratedSessionSuffix ?
wem.digitalData.wemInitConfig.browserGeneratedSessionSuffix : '';
+ wem.disableTrackedConditionsListeners =
wem.digitalData.wemInitConfig.disableTrackedConditionsListeners;
+ wem.activateWem = wem.digitalData.wemInitConfig.activateWem;
+ var _wem$digitalData$wemI = wem.digitalData.wemInitConfig,
+ contextServerUrl = _wem$digitalData$wemI.contextServerUrl,
+ timeoutInMilliseconds = _wem$digitalData$wemI.timeoutInMilliseconds,
+ contextServerCookieName =
_wem$digitalData$wemI.contextServerCookieName;
+ wem.contextServerCookieName = contextServerCookieName;
+ wem.contextServerUrl = contextServerUrl;
+ wem.timeoutInMilliseconds = timeoutInMilliseconds;
+ wem.formNamesToWatch = [];
+ wem.eventsPrevented = [];
+ wem.sessionID = wem.getCookie(wem.trackerSessionIdCookieName);
+ wem.fallback = false;
+
+ if (wem.sessionID === null) {
+ console.warn('[WEM] sessionID is null !');
+ } else if (!wem.sessionID || wem.sessionID === '') {
+ console.warn('[WEM] empty sessionID, setting to null !');
+ wem.sessionID = null;
+ }
+ },
+
+ /**
+ * This function start the tracker by loading the context in the page
+ * Note: that the tracker will start once the current DOM is complete
loaded, using listener on current document: DOMContentLoaded
+ *
+ * @param {object[]} digitalDataOverrides optional, list of digitalData
extensions, they will be merged with original digitalData before context loading
+ * @returns {undefined}
+ */
+ startTracker: function startTracker() {
+ var digitalDataOverrides = arguments.length > 0 && arguments[0] !==
undefined ? arguments[0] : undefined;
+ // Check before start
+ var cookieDisabled = !navigator.cookieEnabled;
+ var noSessionID = !wem.sessionID || wem.sessionID === '';
+ var crawlerDetected = navigator.userAgent;
+
+ if (crawlerDetected) {
+ var browserDetector = new es6CrawlerDetect.Crawler();
+ crawlerDetected = browserDetector.isCrawler(navigator.userAgent);
+ }
+
+ if (cookieDisabled || noSessionID || crawlerDetected) {
+ document.addEventListener('DOMContentLoaded', function () {
+ wem._executeFallback('navigator cookie disabled: ' + cookieDisabled
+ ', no sessionID: ' + noSessionID + ', web crawler detected: ' +
crawlerDetected);
+ });
+ return;
+ } // Register base context callback
+
+
+ wem._registerCallback(function () {
+ if (wem.cxs.profileId) {
+ wem.setCookie(wem.trackerProfileIdCookieName, wem.cxs.profileId);
+ }
+
+ if (!wem.cxs.profileId) {
+ wem.removeCookie(wem.trackerProfileIdCookieName);
+ }
+
+ if (!wem.disableTrackedConditionsListeners) {
+ wem._registerListenersForTrackedConditions();
+ }
+ }, 'Default tracker', 0); // Load the context once document is ready
+
+
+ document.addEventListener('DOMContentLoaded', function () {
+ wem.DOMLoaded = true; // enrich digital data considering extensions
+
+ wem._handleDigitalDataOverrides(digitalDataOverrides); // complete
already registered events
+
+
+ wem._checkUncompleteRegisteredEvents(); // Dispatch javascript events
for the experience (perso/opti displayed from SSR, based on unomi events)
+
+
+ wem._dispatchJSExperienceDisplayedEvents(); // Some event may not need
to be send to unomi, check for them and filter them out.
+
+
+ wem._filterUnomiEvents(); // Add referrer info into digitalData.page
object.
+
+
+ wem._processReferrer(); // Build view event
+
+
+ var viewEvent = wem.buildEvent('view', wem.buildTargetPage(),
wem.buildSource(wem.digitalData.site.siteInfo.siteID, 'site'));
+ viewEvent.flattenedProperties = {}; // Add URLParameters
+
+ if (location.search) {
+ viewEvent.flattenedProperties['URLParameters'] =
wem.convertUrlParametersToObj(location.search);
+ } // Add interests
+
+
+ if (wem.digitalData.interests) {
+ viewEvent.flattenedProperties['interests'] =
wem.digitalData.interests;
+ } // Register the page view event, it's unshift because it should be
the first event, this is just for logical purpose. (page view comes before
perso displayed event for example)
+
+
+ wem._registerEvent(viewEvent, true);
+
+ if (wem.activateWem) {
+ wem.loadContext();
+ } else {
+ wem._executeFallback('wem is not activated on current page');
+ }
+ });
+ },
+
+ /**
+ * get the current loaded context from Unomi, will be accessible only
after loadContext() have been performed
+ * @returns {object} loaded context
+ */
+ getLoadedContext: function getLoadedContext() {
+ return wem.cxs;
+ },
+
+ /**
+ * In case Unomi contains rules related to HTML forms in the current page.
+ * The logic is simple, in case a rule exists in Unomi targeting a form
event within the current webpage path
+ * - then this form will be identified as form to be watched.
+ * You can reuse this function to get the list of concerned forms in order
to attach listeners automatically for those form for example
+ * (not that current tracker is doing that by default, check function:
_registerListenersForTrackedConditions())
+ * @returns {string[]} form names/ids in current web page
+ */
+ getFormNamesToWatch: function getFormNamesToWatch() {
+ return wem.formNamesToWatch;
+ },
+
+ /**
+ * Get current session id
+ * @returns {null|string} get current session id
+ */
+ getSessionId: function getSessionId() {
+ return wem.sessionID;
+ },
+
+ /**
+ * This function will register a personalization
+ *
+ * @param {object} personalization the personalization object
+ * @param {object} variants the variants
+ * @param {boolean} [ajax] Deprecated: Ajax rendering is not supported
anymore
+ * @param {function} [resultCallback] the callback to be executed after
personalization resolved
+ * @returns {undefined}
+ */
+ registerPersonalizationObject: function
registerPersonalizationObject(personalization, variants, ajax, resultCallback) {
+ var target = personalization.id;
+
+ wem._registerPersonalizationCallback(personalization, function (result) {
+ var successfulFilters = [];
+
+ for (var i = 0; i < result.length; i++) {
+ successfulFilters.push(variants[result[i]]);
+ }
+
+ var selectedFilter = null;
+
+ if (successfulFilters.length > 0) {
+ selectedFilter = successfulFilters[0];
+ var minPos = successfulFilters[0].position;
+
+ if (minPos >= 0) {
+ for (var j = 1; j < successfulFilters.length; j++) {
+ if (successfulFilters[j].position < minPos) {
+ selectedFilter = successfulFilters[j];
+ }
+ }
+ }
+ }
+
+ if (resultCallback) {
+ // execute callback
+ resultCallback(successfulFilters, selectedFilter);
+ } else {
+ if (selectedFilter) {
+ var targetFilters = document.getElementById(target).children;
+
+ for (var fIndex in targetFilters) {
+ var filter = targetFilters.item(fIndex);
+
+ if (filter) {
+ filter.style.display = filter.id === selectedFilter.content ?
'' : 'none';
+ }
+ } // we now add control group information to event if the user is
in the control group.
+
+
+ if (wem._isInControlGroup(target)) {
+ console.info('[WEM] Profile is in control group for target: ' +
target + ', adding to personalization event...');
+ selectedFilter.event.target.properties.inControlGroup = true;
+
+ if (selectedFilter.event.target.properties.variants) {
+
selectedFilter.event.target.properties.variants.forEach(function (variant) {
+ return variant.inControlGroup = true;
+ });
+ }
+ } // send event to unomi
+
+
+ wem.collectEvent(wem._completeEvent(selectedFilter.event),
function () {
+ console.info('[WEM] Personalization event successfully
collected.');
+ }, function () {
+ console.error('[WEM] Could not send personalization event.');
+ }); //Trigger variant display event for personalization
+
+ wem._dispatchJSExperienceDisplayedEvent(selectedFilter.event);
+ } else {
+ var elements = document.getElementById(target).children;
+
+ for (var eIndex in elements) {
+ var el = elements.item(eIndex);
+ el.style.display = 'none';
+ }
+ }
+ }
+ });
+ },
+
+ /**
+ * This function will register an optimization test or A/B test
+ *
+ * @param {string} optimizationTestNodeId the optimization test node id
+ * @param {string} goalId the associated goal Id
+ * @param {string} containerId the HTML container Id
+ * @param {object} variants the variants
+ * @param {boolean} [ajax] Deprecated: Ajax rendering is not supported
anymore
+ * @param {object} [variantsTraffic] the associated traffic allocation
+ * @return {undefined}
+ */
+ registerOptimizationTest: function
registerOptimizationTest(optimizationTestNodeId, goalId, containerId, variants,
ajax, variantsTraffic) {
Review Comment:
goalId, containerId and ajax are not used by the function do we want to keep
them?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]