/**
* @class
* @classdesc Plugin used to manage technical side of clicks : redirections, forms submit and mailto actions.
* @name TechClicks
* @memberof ATInternet.Tracker.Plugins
* @type {function}
* @param parent {object} Instance of the Tag used
* @public
*/
window['ATInternet']['Tracker']['Plugins']['TechClicks'] = function (parent) {
"use strict";
var _this = this;
// Plugin configuration.
var _clicksAutoManagementEnabled,
_clicksAutoManagementTimeout;
parent.configPlugin('TechClicks', dfltPluginCfg || {}, function (newConf) {
_clicksAutoManagementEnabled = newConf['clicksAutoManagementEnabled'];
_clicksAutoManagementTimeout = newConf['clicksAutoManagementTimeout'];
});
/**
* Deactivate the automatic management (redirection/submit/mailto) for clicks on the current page.
* @name deactivateAutoManagement
* @memberof ATInternet.Tracker.Plugins.TechClicks#
* @function
* @public
*/
_this['deactivateAutoManagement'] = function () {
_clicksAutoManagementEnabled = false;
};
//*************************************************************************************************
// PART FOR MANAGING REDIRECTION/SUBMIT/MAILTO ACTIONS AND LISTENER
//*************************************************************************************************
/**
* Do a redirection with a given url & target.
* @memberof ATInternet.Tracker.Plugins.TechClicks#
* @function
* @param contextObj {object} Redirection's url and target (properties url & target)
* @private
*/
var _doRedirection = function (contextObj) {
switch (contextObj['target']) {
case '_top':
window.top.location.href = contextObj['url'];
break;
case '_parent':
window.parent.location.href = contextObj['url'];
break;
default:
window.location.href = contextObj['url'];
break;
}
};
/**
* Do a setTimeout with the action concerned with the current process (redirection/submit/mailto).
* @memberof ATInternet.Tracker.Plugins.TechClicks#
* @function
* @param contextObject {object} Context object containing data for the case it must be done (redirection/submit/mailto) Properties timeout, mailto, form, url, target
* @private
*/
var _addTimeout = function (contextObject) {
var timeout = contextObject['timeout'];
if (contextObject['mailto']) {
setTimeout(function () {
window.location.href = contextObject['mailto'];
}, timeout);
} else if (contextObject['form']) {
setTimeout(function () {
contextObject['form'].submit();
}, timeout);
} else if (contextObject['url']) {
setTimeout(function () {
_doRedirection({url: contextObject['url'], target: contextObject['target']});
}, timeout);
}
};
/**
* Allow to know if this is an action case (nothing should happen).
* @memberof ATInternet.Tracker.Plugins.TechClicks#
* @function
* @param DOMElement {object} The clicked element
* @return {boolean}
* @private
*/
var _isAction = function (DOMElement) {
// checks 3 attributes (HREF,TARGET,DATA-ATCLICKREDIR) :
// first we check the target and data-atclickmanagement because they are prior to href check
var element = DOMElement;
while (element) {
if (typeof element.getAttribute === 'function') {
if (element.getAttribute('target') === '_blank') {
return true;
}
if (element.getAttribute('data-atclickmanagement') === 'no') {
return true;
}
}
element = element.parentNode;
}
// then we check href
element = DOMElement;
var currentUrl = window.location.href,
newUrl;
while (element) {
// do not use getAttribute here, it gets the value exactly as it is and not the URL complete (so you will get '#anchor' instead of 'http....#anchor'
newUrl = element['href'];
if (newUrl &&
newUrl.indexOf('#') > 0 &&
currentUrl.substring(0, (currentUrl.indexOf('#') > 0 ? currentUrl.indexOf('#') : currentUrl.length)) ===
newUrl.substring(0, newUrl.indexOf('#'))) {
// same base URL until anchor (#), if no anchor in the new url, it will do a navigation
return true;
}
element = element.parentNode;
}
return false;
};
/**
* Get redirection data and wait for the hit to be sent to trigger the redirection (a timeout will trigger it if it's too long).
* @memberof ATInternet.Tracker.Plugins.TechClicks#
* @function
* @param DOMElement {object} The clicked element
* @private
*/
var _manageRedirection = function (DOMElement) {
var url, target = '_self';
var element = DOMElement,
timeoutOnly = element['timeoutonly'];
while (element) {
if (element['href'] && (element['href'].indexOf('http') === 0)) {
url = element['href'].split('"').join('\\"');
target = (element['target'] ? element['target'] : target);
break;
}
element = element.parentNode;
}
if (url) {
if (!timeoutOnly) {
parent.onTrigger('Tracker:Hit:Sent:Ok', function () {
// multihits not managed for the moment, the first hit sent will trigger the redirection
_doRedirection({url: url, target: target});
});
}
_addTimeout({url: url, target: target, timeout: _clicksAutoManagementTimeout});
}
};
/**
* Get form data and wait for the hit to be sent to trigger the submit (a timeout will trigger it if it's too long).
* @memberof ATInternet.Tracker.Plugins.TechClicks#
* @function
* @param DOMElement {object} The clicked element
* @private
*/
var _manageFormSubmit = function (DOMElement) {
var element = DOMElement,
timeoutOnly = element['timeoutonly'];
while (element) {
if (element.nodeName === 'FORM') {
break;
}
element = element.parentNode;
}
if (element) {
if (!timeoutOnly) {
parent.onTrigger('Tracker:Hit:Sent:Ok', function () {
// multihits not managed for the moment, the first hit sent will trigger the submit
element.submit();
});
}
_addTimeout({form: element, timeout: _clicksAutoManagementTimeout});
}
};
/**
* Get mailto data and wait for the hit to be sent to trigger the mailto (a timeout will trigger it if it's too long).
* @memberof ATInternet.Tracker.Plugins.TechClicks#
* @function
* @private
* @param DOMElement {object} The clicked element
*/
var _manageMailto = function (DOMElement) {
var element = DOMElement,
timeoutOnly = element['timeoutonly'];
while (element) {
if (element['href'] && element['href'].indexOf('mailto:') >= 0) {
break;
}
element = element.parentNode;
}
if (element) {
if (!timeoutOnly) {
parent.onTrigger('Tracker:Hit:Sent:Ok', function () {
// multihits not managed for the moment, the first hit sent will trigger the mailto
window.location.href = element['href'];
});
}
_addTimeout({mailto: element['href'], timeout: _clicksAutoManagementTimeout});
}
};
/**
* Return the case we should consider ('mailto', 'form' or 'redirection'). Return false if we don't find the minimum requirement
* @memberof ATInternet.Tracker.Plugins.TechClicks#
* @function
* @param DOMElement {object} The clicked element
* @return {string|false}
* @private
*/
var _getCurrentCase = function (DOMElement) {
var element = DOMElement;
while (element) {
if (element['href']) {
if (element['href'].indexOf('mailto:') >= 0) {
return 'mailto';
} else if (element['href'].indexOf('http') === 0) {
return 'redirection';
}
} else if (element.nodeName === 'FORM') {
return 'form';
}
element = element.parentNode;
}
return false;
};
/**
* Take a DOM element (possibly with an event), check if this is a case that should be managed, return false if this is the case
* (or preventdefault for the event) and call the manager corresponding to the current case (redirection/mailto/submit).
* Return true if nothing will be done.
* @name manageClick
* @memberof ATInternet.Tracker.Plugins.TechClicks#
* @function
* @param DOMElement {object} The clicked element
* @param eventObj {object} The event object provided when triggered
* @param callback {function} callback to execute
* @return {boolean}
* @public
*/
_this['manageClick'] = function (DOMElement, eventObj, callback) {
var preservePropagation = true;
if (_clicksAutoManagementEnabled && DOMElement) { // process activated and element provided
var action = _isAction(DOMElement),
elementType = _getCurrentCase(DOMElement);
if (!action && elementType) { // priority is to know if this is an action, if not, we check mailto then submit then redirection
switch (elementType) {
case 'mailto':
_manageMailto(DOMElement);
preservePropagation = false;
break;
case 'form':
_manageFormSubmit(DOMElement);
preservePropagation = false;
break;
case 'redirection':
_manageRedirection(DOMElement);
preservePropagation = false;
break;
default:
// we didn't find what we needed to manage any case
break;
}
}
}
// code to deactivate the event (click/submit)
if (eventObj) {
var defaultPrevented = eventObj.defaultPrevented;
if (typeof eventObj.isDefaultPrevented === 'function') {
defaultPrevented = eventObj.isDefaultPrevented();
}
if (!defaultPrevented) {
eventObj.preventDefault && eventObj.preventDefault();
}
}
callback && callback();
return preservePropagation;
};
// For unit tests on private elements !!!
/* @if test */
_this['_isAction'] = _isAction;
_this['_getCurrentCase'] = _getCurrentCase;
_this['_manageRedirection'] = _manageRedirection;
_this['_doRedirection'] = _doRedirection;
_this['_manageFormSubmit'] = _manageFormSubmit;
_this['_manageMailto'] = _manageMailto;
_this['_addTimeout'] = _addTimeout;
_this['_clicksAutoManagementEnabled'] = _clicksAutoManagementEnabled;
_this['_clicksAutoManagementTimeout'] = _clicksAutoManagementTimeout;
_this['getThemAll'] = function () {
_this['_clicksAutoManagementEnabled'] = _clicksAutoManagementEnabled;
_this['_clicksAutoManagementTimeout'] = _clicksAutoManagementTimeout;
};
_this['setInternalVar'] = function (name, val) {
if (name === '_clicksAutoManagementEnabled') _clicksAutoManagementEnabled = val;
if (name === '_clicksAutoManagementTimeout') _clicksAutoManagementTimeout = val;
};
/* @endif */
};
window['ATInternet']['Tracker']['addPlugin']('TechClicks');