import customEvent from '../utils/customEvent';
/**
* Module for handling Adobe Analytics
*
* @module AdobeAnalyticsHelper
*/
const AdobeAnalyticsHelper = {
account: 'corus-testing-globalnews',
trackingServer: 'metrics.corus.ca',
securedTrackingServer: 'smetrics.corus.ca',
visitorId: '5F34123F5245B4A70A490D45@AdobeOrg',
convertToLowercase: true,
contentNamespace: 'content',
pageSections: [],
pageData: {},
pageTrackingDisabled: false,
s: {},
/*
* Initialize and configure AppMeasurement for adobe analytics.
* Fires a page tracking call when executed.
*
* @method init
*/
init() {
/* global gnAnalyticsSettings */
// Get configuration settings from page
if ( 'undefined' !== typeof ( gnAnalyticsSettings ) && 'undefined' !== typeof ( gnAnalyticsSettings.adobe ) ) {
if ( gnAnalyticsSettings.adobe.accounts ) {
this.account = gnAnalyticsSettings.adobe.accounts;
}
if ( gnAnalyticsSettings.adobe.trackingDomain ) {
this.trackingServer = gnAnalyticsSettings.adobe.trackingDomain;
}
if ( gnAnalyticsSettings.adobe.StrackingDomain ) {
this.securedTrackingServer = gnAnalyticsSettings.adobe.StrackingDomain;
}
if ( gnAnalyticsSettings.adobe.disablePageTracking ) {
this.pageTrackingDisabled = true;
}
}
// Initialize AppMeasurement
/* eslint-disable camelcase */
const s = 'undefined' !== typeof ( s_gi ) ? s_gi( this.account ) : null; // eslint-disable-line no-undef, s_gi is AppMeasurement function
if ( this.isUndefinedOrEmpty( s ) ) {
return;
}
/* eslint-enable camelcase */
// Configure AppMeasurement
s.trackingServer = this.trackingServer;
s.trackingServerSecure = this.securedTrackingServer;
s.currencyCode = 'CAD';
s.trackDownloadLinks = true;
s.trackExternalLinks = true;
s.trackInlineStats = true;
s.linkDownloadFileTypes = 'exe,zip,wav,mp3,mov,mpg,avi,wmv,pdf,doc,docx,xls,xlsx,ppt,pptx';
s.linkInternalFilters = 'globalnews.ca,globalnews-ca-develop.go-vip.net';
s.linkLeaveQueryString = false;
s.linkTrackEvents = 'None';
s.linkTrackVars = 'None';
s.pathConcatDelim = '|';
s.usePlugins = true;
s.doPlugins = () => {
this.doPlugins();
};
/* global gnPageData */
const gnPageDataExists = 'undefined' !== typeof ( gnPageData );
const pageData = gnPageDataExists ? gnPageData : {};
pageData.context_data = gnPageDataExists ? gnPageData.context_data : {};
pageData.props = gnPageDataExists ? gnPageData.props : {};
pageData.sections = gnPageDataExists ? gnPageData.sections : [];
// Set other default page data
pageData.context_data.sitename = 'globalnews';
pageData.context_data.server = document.domain;
// Set content title if not already set
if ( ! pageData.context_data.title ) {
pageData.context_data.title = document.title;
}
// Page referrer
let { referrer } = pageData.context_data;
if ( ! referrer ) {
if ( document.location.href.toLowerCase().indexOf( 'campaign_id=a100' ) > 0 ) {
referrer = 'https://apple-news-article.apple.com/';
} else {
({ referrer } = document );
}
pageData.context_data.referrer = referrer;
}
s.referrer = referrer;
// Copy props set up before s was initialized by external scripts
const { s: sObj } = window;
if ( sObj ) {
const sKeys = Object.keys( sObj );
[].forEach.call( sKeys, ( key ) => {
const val = sObj[key];
if ( 0 === key.indexOf( 'prop' ) ) {
if ( 'prop71' === key ) {
pageData.context_data['watson.top'] = val;
} else if ( 'prop72' === key ) {
pageData.context_data['watson.category'] = val;
} else {
s[key] = val;
}
} else if ( key.indexOf( '.' ) > 0 && 'string' === typeof ( val ) ) {
// Assign context data set prior to s object instantiation
pageData.context_data[key] = val;
} else if ( 'contextData' === key ) {
const { contextData: cd } = sObj;
Object.assign( pageData.context_data, cd );
}
});
}
// Pick up context data assigned to global variable CorusContextData
const { CorusContextData: corusData } = window;
if ( corusData ) {
Object.assign( pageData.context_data, corusData );
}
// Load video mopdule if required
if ( 'video' === pageData.context_data.contenttype ) {
s.loadModule( 'Media' );
s.Media.autoTrack = false;
s.Media.trackWhilePlaying = true;
s.Media.trackVars = 'None';
s.Media.trackEvents = 'None';
s.Media.playerName = 'CorusVideoPlayer-html5';
}
/* global Visitor */
// Adding VisitorAPI to AppMeasurement
if ( 'undefined' !== typeof ( Visitor ) ) {
const visitor = Visitor.getInstance( this.visitorId );
s.visitor = visitor;
s.prop1 = 'VisitorAPI Present';
pageData.context_data['adobe.mid'] = visitor.getMarketingCloudVisitorID();
} else {
s.prop1 = 'VisitorAPI Missing';
}
// Get PWA browser mode
let displayMode = 'browser';
const isStandalone = window.matchMedia( '(display-mode: standalone)' ).matches;
if ( /^android-app:\/\//.test( document.referrer ) ) {
displayMode = 'twa';
} else if ( navigator.standalone || isStandalone ) {
displayMode = 'standalone';
}
pageData.context_data['pwa.mode'] = displayMode;
this.s = s;
this.addPlugins();
this.applyUtmCode();
this.setPageData( pageData );
this.setupActivityMap();
customEvent.fire( document, 'pageDataReady', {
data: this.s.contextData,
});
// trigger page tracking call, unless disabled for specific pages.
if ( true !== this.pageTrackingDisabled ) {
this.s.tl();
}
},
/*
* Called by AppMeasurement when a tracking call is made
*
* @method doPlugins
*/
doPlugins() {
},
/*
* Generate link tracking call
*
* @param {Object|boolean} clickedTarget - HTML element clicked or 'true'
* @param {String} linkType - 'o' for custom link tracking, 'e' for exit links
* @param {Object} data - optional. key value pairs to be tracked as context data
* @param {Boolean} convertToLower - optional. if 'true', convert context data to lower case
* @method trackLink
*/
trackLink( clickedTarget, linkType, linkName, data, convertToLower ) {
const keys = data ? Object.keys( data ) : false;
const shouldConvert = 'undefined' !== typeof ( convertToLower ) ? convertToLower : this.convertToLowercase;
if ( keys && keys.length > 0 ) {
this.s.linkTrackVars = '';
this.s.contextData = this.s.contextData || {};
[].forEach.call( keys, ( key ) => {
const lcKey = key.toLowerCase(); // Key always reported in lower case.
this.s.contextData[lcKey] = shouldConvert ? data[key].toLowerCase() : data[key];
this.s.linkTrackVars = `${this.s.linkTrackVars},contextData.${lcKey}`;
});
}
let action = null;
const name = shouldConvert ? linkName.toLowerCase() : linkName;
// only navigate to target URL if clickedTarget is a link and has target _blank
if ( clickedTarget
&& 'boolean' !== typeof ( clickedTarget )
&& clickedTarget.getAttribute( 'href' )
&& '_blank' !== clickedTarget.getAttribute( 'target' ) ) {
action = 'navigate';
}
// when clickedTarget is 'true', no delay will be applied as user isn't leaving current page
// otherwise, tracking call will redirect to clickedTarget's link after 500ms
// to ensure the tracking event got fired before exiting the page
this.s.tl( clickedTarget, linkType, name, null, action );
this.s.linkTrackVars = 'None';
},
/*
* Set contextData in AppMeasurement to be tracked
* e.g. s.contextData[namespace.key] = value
*
* @param {String} key - Key of context data. if key contains '.', the prefix is used as namespace
* @param {String} value - Value of context data
* @param {String} namespace - Optional. Defaults to 'content'
* @method setContextData
*/
setContextData( key, value, namespace ) {
if ( this.isUndefinedOrEmpty( this.s ) || ! key || ! value ) {
return;
}
let ns = namespace;
let convertedKey = key;
let convertedVal = value.toString();
if ( ! ns ) {
ns = this.contentNamespace;
const match = new RegExp( '([^\\.]+)\\.(.+)' ).exec( key );
if ( match && match.length > 2 ) {
[, ns, convertedKey] = match;
}
}
if ( this.convertToLowercase ) {
convertedVal = convertedVal.toLowerCase();
}
convertedKey = convertedKey.toLowerCase();
this.s.contextData[`${ns}.${convertedKey}`] = convertedVal;
},
/*
* Processes page data spit out by the page as a global JS variable
* and sets the appropriate tracking props and context data accordingly
*
* @param {Object} pageData
* @method setPageData
*/
setPageData( pageData ) {
this.pageData = pageData;
// Set page sections
this.setPageSections( pageData.sections );
// Set context data variables
[].forEach.call( Object.keys( pageData.context_data ), ( key ) => {
this.setContextData( key, pageData.context_data[key]);
});
// Set props
[].forEach.call( Object.keys( pageData.props ), ( key ) => {
this.s[key] = pageData.props[key];
});
},
/*
* Set page name, sitesection, sitesubsection properties
*
* @param {Array} sections - page name broken down into array of strings
* @param {Number} numLevels - maxnimum number of subsection levels to report
* @method setPageSections
*/
setPageSections( sections, numLevels ) {
if ( this.isUndefinedOrEmpty( this.s ) ) {
return;
}
if ( ! this.pageSections ) {
this.pageSections = sections;
}
const levels = numLevels || 5;
if ( sections && sections.length > 0 ) {
this.setContextData( 'sitesection', sections[0]);
this.setContextData( 'pagename', sections.join( this.s.pathConcatDelim ) );
for ( let i = 0; i <= levels; i += 1 ) {
let sectionName = 'sitesubsection';
if ( i > 1 ) {
sectionName += i;
}
const val = sections.slice( 0, i + 1 ).join( this.s.pathConcatDelim );
this.setContextData( sectionName, val );
}
}
},
/*
* Customize activity map region and link reports
*
* @method setupActivityMap
*/
setupActivityMap() {
if ( 'undefined' !== typeof ( this.s.ActivityMap ) ) {
const originalRegionFunc = this.s.ActivityMap.region;
const originalLinkFunc = this.s.ActivityMap.link;
this.s.ActivityMap.region = ( $elem ) => {
let region = originalRegionFunc( $elem );
if ( $elem && $elem.dataset.trackRegion ) {
region = $elem.dataset.trackRegion;
} else if ( region && /player_.+__sticky/.test( region ) ) {
region = 'stickyVideo';
}
const group = this.s.contextData && '1' === this.s.contextData['content.beta'] ? '-beta' : '';
return `${region}${group}`;
};
this.s.ActivityMap.link = ( $elem ) => {
let link = originalLinkFunc( $elem );
if ( $elem ) {
if ( $elem.dataset.trackLink ) {
link = $elem.dataset.trackLink;
} else if ( 'a' === $elem.nodeName.toLowerCase() ) {
const title = $elem.getAttribute( 'title' );
if ( title ) {
link = title;
}
}
}
return link;
};
}
},
/*
* Sets appropriate props and campaign values for UTM tracking
*
* @method applyUtmCode
*/
applyUtmCode() {
// UTM tracking
let campaign = '';
let trackVal = this.s.Util.getQueryParam( 'utm_medium' );
if ( trackVal ) {
this.s.eVar18 = trackVal;
campaign += trackVal + this.s.pathConcatDelim;
}
trackVal = this.s.Util.getQueryParam( 'utm_source' );
if ( trackVal ) {
this.s.eVar19 = trackVal;
campaign += trackVal + this.s.pathConcatDelim;
}
trackVal = this.s.Util.getQueryParam( 'utm_campaign' );
if ( trackVal ) {
this.s.eVar20 = trackVal;
campaign += trackVal + this.s.pathConcatDelim;
}
trackVal = this.s.Util.getQueryParam( 'utm_term' );
if ( trackVal ) {
this.s.eVar21 = trackVal;
campaign += trackVal + this.s.pathConcatDelim;
}
trackVal = this.s.Util.getQueryParam( 'utm_content' );
if ( trackVal ) {
this.s.eVar22 = trackVal;
campaign += trackVal + this.s.pathConcatDelim;
}
if ( '' !== campaign ) {
this.s.campaign = campaign;
}
},
/*
* Add vendor plugins
*
* @method addPlugins
*/
addPlugins() {
/* eslint-disable */
/*
* Plugin: getValOnce 0.2 - get a value once per session or number of days
*/
this.s.getValOnce=new Function("v","c","e",""
+"var s=this,k=s.c_r(c),a=new Date;e=e?e:0;if(v){a.setTime(a.getTime("
+")+e*86400000);s.c_w(c,v,e?a:0);}return v==k?'':v");
/*
* Plugin: getTimeParting 3.4
*/
this.s.getTimeParting=new Function("h","z",""
+"var s=this,od;od=new Date('1/1/2000');if(od.getDay()!=6||od.getMont"
+"h()!=0){return'Data Not Available';}else{var H,M,D,U,ds,de,tm,da=['"
+"Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturda"
+"y'],d=new Date();z=z?z:0;z=parseFloat(z);if(s._tpDST){var dso=s._tp"
+"DST[d.getFullYear()].split(/,/);ds=new Date(dso[0]+'/'+d.getFullYea"
+"r());de=new Date(dso[1]+'/'+d.getFullYear());if(h=='n'&&d>ds&&d<de)"
+"{z=z+1;}else if(h=='s'&&(d>de||d<ds)){z=z+1;}}d=d.getTime()+(d.getT"
+"imezoneOffset()*60000);d=new Date(d+(3600000*z));H=d.getHours();M=d"
+".getMinutes();M=(M<10)?'0'+M:M;D=d.getDay();U=' AM';if(H>=12){U=' P"
+"M';H=H-12;}if(H==0){H=12;}D=da[D];tm=H+':'+M+U;return(tm+'|'+D);}");
/*
* Plugin Utility: apl v1.1
*/
this.s.apl=new Function("l","v","d","u",""
+"var s=this,m=0;if(!l)l='';if(u){var i,n,a=s.split(l,d);for(i=0;i<a."
+"length;i++){n=a[i];m=m||(u==1?(n==v):(n.toLowerCase()==v.toLowerCas"
+"e()));}}if(!m)l=l?l+d+v:v;return l");
/*
* Utility Function: split v1.5 - split a string (JS 1.0 compatible)
*/
this.s.split=new Function("l","d",""
+"var i,x=0,a=new Array;while(l){i=l.indexOf(d);i=i>-1?i:l.length;a[x"
+"++]=l.substring(0,i);l=l.substring(i+d.length);}return a");
/*
* Plugin: linkHandler 0.5 - identify and report custom links
*/
this.s.linkHandler=new Function("p","t",""
+"var s=this,h=s.p_gh(),i,l;t=t?t:'o';if(!h||(s.linkType&&(h||s.linkN"
+"ame)))return '';i=h.indexOf('?');h=s.linkLeaveQueryString||i<0?h:h."
+"substring(0,i);l=s.pt(p,'|','p_gn',h.toLowerCase());if(l){s.linkNam"
+"e=l=='[['?'':l;s.linkType=t;return h;}return '';");
this.s.p_gn=new Function("t","h",""
+"var i=t?t.indexOf('~'):-1,n,x;if(t&&h){n=i<0?'':t.substring(0,i);x="
+"t.substring(i+1);if(h.indexOf(x.toLowerCase())>-1)return n?n:'[[';}"
+"return 0;");
/*
* Utility Function: p_gh
*/
this.s.p_gh=new Function(""
+"var s=this;if(!s.eo&&!s.lnk)return '';var o=s.eo?s.eo:s.lnk,y=s.ot("
+"o),n=s.oid(o),x=o.s_oidt;if(s.eo&&o==s.eo){while(o&&!n&&y!='BODY'){"
+"o=o.parentElement?o.parentElement:o.parentNode;if(!o)return '';y=s."
+"ot(o);n=s.oid(o);x=o.s_oidt}}return o.href?o.href:'';");
/*
* Utility Function: p_c
*/
this.s.p_c=new Function("v","c",""
+"var x=v.indexOf('=');return c.toLowerCase()==v.substring(0,x<0?v.le"
+"ngth:x).toLowerCase()?v:0");
/* eslint-enable */
},
/*
* Check if AppMeasurement is defined, it may not be when ad blocker is enabled
*
* @param {Object} s - AppMeasurement object to check
* @return {Boolean} true if s is defined, not empty, not null
* @method isUndefinedOrEmpty
*/
isUndefinedOrEmpty( s ) {
return ( 'undefined' === typeof ( s ) ) || null === s || 0 === s.length;
},
};
export default AdobeAnalyticsHelper;