File: /var/www/html/wp-content/plugins/advanced-ads-pro/src/js/advanced-ads-pro.js
/* eslint-disable */
( function ( $ ) {
// CFP cookies prefix
var cname = 'advads_procfp';
var cname_vc = 'advanced_ads_ad_clicks'; // visitor conditions
// CFP cookies parameter ( domain/path )
var PATH = null;
var DOMAIN = null;
/**
* wrapper for JSON.parse
*/
function jsonDecode( str ) {
try {
var res = JSON.parse( str );
return res;
} catch ( Ex ) {
return null;
}
}
// Max ad click conditions/ passive Cache busting.
$( document ).on( 'advads-passive-cb-conditions', function ( e, cbs ) {
cbs.conditions[ 'ad_clicks' ] = 'check_ad_clicks';
cbs[ 'check_ad_clicks' ] = function ( options, ad ) {
if ( advads.cookie_exists( cname_vc + '_' + ad.id ) ) {
var C_vc = advads.get_cookie( cname_vc + '_' + ad.id );
C_vc = jsonDecode( C_vc );
}
if ( C_vc ) {
var now = parseInt( new Date().getTime() / 1000 );
for ( var i in C_vc ) {
if ( '_' + options.expiration == i ) {
// if still valid counter and click limit reached
if (
C_vc[ i ][ 'ttl' ] >= now &&
C_vc[ i ][ 'count' ] >= parseInt( options.limit )
) {
return false;
}
}
}
}
return true;
};
} );
var cfpTracker = function () {
this.$elements = {};
this.currentIFrame = false;
this.focusLost = false;
this.wrappers = [ '.google-auto-placed' ];
this.attributes = {
'data-anchor-status': 'displayed',
'data-vignette-loaded': 'true',
};
this.lastClick = 0;
this.init();
};
cfpTracker.prototype = {
constructor: cfpTracker,
init: function () {
const that = this;
let touchmoved;
// increment counter on click on link
$( document ).on( 'click', 'a[data-cfpa]', function () {
that.onClick( parseInt( $( this ).attr( 'data-cfpa' ) ) );
} );
// Increment counter on blur only if an iframe has recently been hovered.
$( window ).on( 'blur', function ( e ) {
// Use timeout of 0 ms as a workaround to make sure that the active element has changed correctly.
setTimeout( function () {
if ( ! that.currentIFrame ) {
// Loop parent nodes from the target to the delegation node to recognise iframe clicks.
for (
let target = document.activeElement;
target && target !== this && target !== document;
target = target.parentNode
) {
that.currentIFrame = that.checkWrappers( target );
if ( that.currentIFrame ) {
break;
}
}
}
if ( that.currentIFrame ) {
that.onClick( that.currentIFrame );
that.focusLost = true;
top.focus();
}
}, 0 );
} );
// mouse passes over an ad that has not yet been initialized (adsense and other distant ads - OR just an ad that contains no link nor iframes)
$( document ).on( 'mouseenter', 'div[data-cfpa]', function () {
var id = parseInt( $( this ).attr( 'data-cfpa' ) );
that.addElement( id );
} );
// Detect swipe and click on mobile devices.
document.addEventListener(
'touchmove',
function () {
touchmoved = true;
},
false
);
document.addEventListener(
'touchstart',
function () {
touchmoved = false;
},
false
);
// Detect desktop and mobile clicks.
[ 'click', 'touchend' ].forEach( function ( event ) {
document.addEventListener( event, function ( e ) {
// Prevent swipes and simultaneous clicks on wrapper and element as well as fast clicks in a row
if (
touchmoved ||
that.getTimestamp() - that.lastClick < 1
) {
return;
}
let adId = null;
// Loop parent nodes from the target to the delegation node.
for (
let target = e.target;
target && target !== this && target !== document;
target = target.parentNode
) {
// Loop all predefined wrappers to detect clicks on Google Auto Ads iframes.
adId = that.checkWrappers( target );
if ( adId ) {
that.onClick( adId );
break;
}
// Check if clicked element is a cfp wrapper.
if (
target.hasAttribute( 'data-cfpa' ) &&
target.hasAttribute( 'data-cfptl' )
) {
adId = parseInt(
target.getAttribute( 'data-cfpa' ),
10
);
that.onClick( adId );
break;
}
}
} );
} );
},
/**
* Create current timestamp
*
* @return {number}
*/
getTimestamp: function () {
return Math.floor( Date.now() / 1000 );
},
/**
* Check if target element is a predefined wrapper or has Google Auto Ads attributes.
*
* @param target
* @returns {string|null}
*/
checkWrappers: function ( target ) {
for (
let i = 0,
wrappersLength = this.wrappers.length,
selector = null;
i < wrappersLength;
i++
) {
selector = this.wrappers[ i ];
if ( target.matches && target.matches( selector ) ) {
return selector === '.google-auto-placed'
? 'google-auto-placed'
: null;
}
}
for ( const [ key, value ] of Object.entries( this.attributes ) ) {
if (
target.hasAttribute( key ) &&
target.getAttribute( key ) === value
) {
return 'google-auto-placed';
}
}
return null;
},
addElement: function ( $el ) {
if ( false === $el instanceof jQuery ) {
// Select the first ad since there may be multiple copies of the same ad on the page.
$el = $( 'div[data-cfpa="' + $el + '"]' ).first();
}
var hasIframe = $el.find( 'iframe' ).length ? true : false;
if ( ! hasIframe ) {
if ( ! $el.find( 'a' ).length ) {
// no an anchor and no iframe -- likely and ad that is not yet loaded (adsense or other ad network)
return;
}
}
var adID = parseInt( $el.attr( 'data-cfpa' ) );
this.$elements[ adID ] = $el;
// remove attribute from the wrapper
$el.removeAttr( 'data-cfpa' );
// And then move it to the first anchor or iframe found
if ( hasIframe ) {
$el.find( 'iframe' ).first().attr( {
'data-cfpa': adID,
} );
if ( $el.attr( 'data-cfph' ) ) {
$el.find( 'iframe' )
.first()
.attr( {
'data-cfph': $el.attr( 'data-cfph' ),
} );
}
} else {
$el.find( 'a' ).not( '.advads-edit-button' ).first().attr( {
'data-cfpa': adID,
} );
if ( $el.attr( 'data-cfph' ) ) {
$el.find( 'a' )
.not( '.advads-edit-button' )
.first()
.attr( {
'data-cfph': $el.attr( 'data-cfph' ),
} );
}
}
// remove Hours attribute from the wrapper
$el.removeAttr( 'data-cfph' );
// update TTL field for all outdated counter (visitor conditions)
if ( advads.cookie_exists( cname_vc + '_' + adID ) ) {
var C_vc = advads.get_cookie( cname_vc + '_' + adID );
C_vc = jsonDecode( C_vc );
if ( C_vc ) {
var now = parseInt( new Date().getTime() / 1000 ),
cookie_modified = false;
for ( var i in C_vc ) {
if ( ! C_vc.hasOwnProperty( i ) ) continue;
if ( 'exp' == i ) continue;
if ( C_vc[ i ][ 'ttl' ] < now ) {
var period = parseFloat( i.substr( 1 ) );
var newTTL = C_vc[ i ][ 'ttl' ];
while ( newTTL < now ) {
newTTL += period * 60 * 60;
}
C_vc[ i ][ 'ttl' ] = newTTL;
C_vc[ i ][ 'count' ] = 0;
cookie_modified = true;
}
}
if ( cookie_modified ) {
var expTime = new Date( C_vc[ 'exp' ] );
advads.set_cookie_sec(
cname_vc + '_' + adID,
JSON.stringify( C_vc, 'false', false ),
parseInt( expTime.getTime() / 1000 ),
PATH,
DOMAIN
);
}
}
}
},
/**
* Ban the visitor
*/
_banVisitor: function () {
var now = new Date();
var d = new Date();
d.setTime(
d.getTime() + advadsCfpInfo.cfpBan * 24 * 60 * 60 * 1000
);
var ban = ( d.getTime() - now.getTime() ) / 1000;
advads.set_cookie_sec( 'advads_pro_cfp_ban', 1, ban, PATH, DOMAIN );
// Select ad wrappers and delete them.
document
.querySelectorAll( '[data-cfpw]:not([data-cfp-exclude])' )
.forEach( function ( el ) {
el.remove();
} );
this.removeEmptyWrappers();
// Select Google AdSense Auto Ads and delete them.
this.wrappers.forEach( function ( wrapper ) {
jQuery( wrapper ).remove();
} );
for ( const [ key, value ] of Object.entries( this.attributes ) ) {
jQuery( '[' + key + '="' + value + '"]' ).remove();
}
},
/**
* Remove top-level wrappers that do not contain ads.
*/
removeEmptyWrappers: function () {
// Select top-level wrappers that are not ads.
document
.querySelectorAll( '[data-cfptl]:not([data-cfpw])' )
.forEach( function ( el ) {
// If there are no nested ads, remove the top-level wrapper.
if ( ! el.querySelectorAll( '[data-cfpw]' ).length ) {
el.remove();
}
} );
},
/**
* Click handler.
*
* @param {string} ID Ad id.
*/
onClick: function ( ID ) {
var that = this,
// Module wide cookie
cookieVisitor = false,
// Visitor condition cookie.
cookieVisitorCondition = false;
this.lastClick = this.getTimestamp();
if (
'google-auto-placed' !== ID &&
$( '[data-cfpa="' + ID + '"]' ).attr( 'data-cfph' )
) {
// if there are some visitor conditions, use the vc cookie
if ( advads.cookie_exists( cname_vc + '_' + ID ) ) {
cookieVisitorCondition = jsonDecode(
advads.get_cookie( cname_vc + '_' + ID )
);
}
const clickLimits = jsonDecode(
$( '[data-cfpa="' + ID + '"]' ).attr( 'data-cfph' )
);
if ( cookieVisitorCondition ) {
// Cookie already exists, increment each counter (keep expiration time)
const nowInSeconds = parseInt(
new Date().getTime() / 1000,
10
);
const adWrapper = document.querySelectorAll(
'[data-cfpw="' + ID + '"]'
);
for ( var h in cookieVisitorCondition ) {
if ( ! cookieVisitorCondition.hasOwnProperty( h ) ) {
continue;
}
if ( h === 'exp' ) {
// Ignore the key that contains expiration date.
continue;
}
cookieVisitorCondition[ h ][ 'count' ] =
parseInt(
cookieVisitorCondition[ h ][ 'count' ],
10
) + 1;
if (
cookieVisitorCondition[ h ][ 'ttl' ] >=
nowInSeconds &&
cookieVisitorCondition[ h ][ 'count' ] >=
parseInt( clickLimits[ h ], 10 )
) {
adWrapper.forEach( function ( node ) {
node.remove();
} );
// If the ad was wrapper with a top-level wrapper, try to remove it.
that.removeEmptyWrappers();
}
}
var now = new Date();
var expiry = new Date( cookieVisitorCondition.exp );
var expirySecs = parseInt(
( expiry.getTime() - now.getTime() ) / 1000
);
advads.set_cookie_sec(
cname_vc + '_' + ID,
JSON.stringify(
cookieVisitorCondition,
'false',
false
),
expirySecs,
PATH,
DOMAIN
);
} else {
// create a new cookie
var cval = {},
maxHValue = 0;
var d = new Date();
var now = new Date();
for ( var h in clickLimits ) {
h = h.substring( 1 );
if ( parseFloat( h ) > maxHValue ) {
maxHValue = parseFloat( h );
}
cval[ '_' + h ] = {
count: 1,
ttl: parseInt(
now.getTime() / 1000 + parseFloat( h ) * 3600,
10
),
};
}
// use the longest hour value for the expiry time
d.setTime( d.getTime() + maxHValue * 60 * 60 * 1000 );
var expires = 'expires=' + d.toUTCString();
var expirySecs = parseInt(
( d.getTime() - now.getTime() ) / 1000
);
cval[ 'exp' ] = expires;
advads.set_cookie_sec(
cname_vc + '_' + ID,
JSON.stringify( cval, 'false', false ),
expirySecs,
PATH,
DOMAIN
);
if (
1 === clickLimits[ Object.keys( clickLimits )[ 0 ] ]
) {
document
.querySelectorAll( '[data-cfpw="' + ID + '"]' )
.forEach( function ( node ) {
node.remove();
} );
this.removeEmptyWrappers();
}
}
}
if ( '1' !== advadsCfpInfo.cfpEnabled ) {
return;
}
// use the module wide CFP cookie
if ( advads.cookie_exists( cname + '_' + ID ) ) {
cookieVisitor = jsonDecode(
advads.get_cookie( cname + '_' + ID )
);
}
if ( cookieVisitor ) {
// Cookie already exists, increment the counter (keep expiration time)
cookieVisitor.count = parseInt( cookieVisitor.count, 10 ) + 1;
var now = new Date();
var expiry = new Date( cookieVisitor.exp );
var expirySecs = ( expiry.getTime() - now.getTime() ) / 1000;
advads.set_cookie_sec(
cname + '_' + ID,
JSON.stringify( cookieVisitor, 'false', false ),
expirySecs,
PATH,
DOMAIN
);
if (
parseInt( advadsCfpInfo.cfpClickLimit, 10 ) <=
cookieVisitor.count
) {
// CFP module enabled - ban this visitor
that._banVisitor();
}
} else {
// create a new cookie
var d = new Date();
var now = new Date();
d.setTime(
d.getTime() +
parseInt( advadsCfpInfo.cfpExpHours, 10 ) *
60 *
60 *
1000
);
var expires = 'expires=' + d.toUTCString();
var expirySecs = ( d.getTime() - now.getTime() ) / 1000;
advads.set_cookie_sec(
cname + '_' + ID,
'{"count":1,"exp":"' + expires + '"}',
expirySecs,
PATH,
DOMAIN
);
if ( parseInt( advadsCfpInfo.cfpClickLimit, 10 ) === 1 ) {
// CFP module enabled - ban this visitor
that._banVisitor();
}
}
},
};
$( function () {
/**
* Max ad click ( visitor conditions )
*/
window.advadsProCfp = new cfpTracker();
// IFRAME click tracking
$( document )
.on( 'mouseenter', 'iframe[data-cfpa]', function ( e ) {
var ID = parseInt( $( this ).attr( 'data-cfpa' ) );
advadsProCfp.currentIFrame = ID;
} )
.on( 'mouseenter', '.google-auto-placed', function ( e ) {
// Use the same ID for all Google AdSense Auto Ads.
advadsProCfp.currentIFrame = 'google-auto-placed';
} )
.on(
'mouseleave mouseout',
'[data-cfpa], .google-auto-placed',
function () {
advadsProCfp.currentIFrame = false;
if ( advadsProCfp.focusLost ) {
advadsProCfp.focusLost = false;
$( window ).trigger( 'focus' );
}
}
);
// construct all elements already present in the queue
for ( var i in advadsCfpQueue ) {
if ( advadsCfpQueue.hasOwnProperty( i ) ) {
advadsProCfp.addElement( advadsCfpQueue[ i ] );
}
}
advadsCfpQueue = [];
/**
* Click fraud protection module.
*/
if ( 'undefined' == typeof window.advadsCfpInfo.cfpPath ) return;
// get the path/domain parameter to use in cookies
if ( '' != advadsCfpInfo.cfpPath ) {
PATH = advadsCfpInfo.cfpPath;
}
if ( '' != advadsCfpInfo.cfpDomain ) {
DOMAIN = advadsCfpInfo.cfpDomain;
}
} );
} )( window.jQuery );
/**
* Reload on resize.
*/
var advanced_ads_resizetimeout = 1000; // time to wait until resized window width is saved, in millisec
var advanced_ads_cookieexpires = 30; // days until the cookie expires
var advanced_ads_browser_width = advanced_ads_get_browser_width();
// Save browserWidth in a cookie if not set or not equal to current saved width.
if ( window.advads !== undefined ) {
var cookieValue = advads.get_cookie( 'advanced_ads_visitor' );
var info = cookieValue ? JSON.parse( cookieValue ) : {};
if (
! info.browser_width ||
info.browser_width !== advanced_ads_browser_width
) {
advanced_ads_save_width( advanced_ads_browser_width );
}
}
// Save new browser width, when window resizes.
if ( window.addEventListener ) {
// most non-IE browsers and IE9
window.addEventListener( 'resize', advanced_ads_resize_window, false );
} else if ( window.attachEvent ) {
// Internet Explorer 5 or above
window.attachEvent( 'onresize', advanced_ads_resize_window );
}
function advanced_ads_resize_window() {
advads_resize_delay( function () {
var previous_width = advanced_ads_browser_width;
advanced_ads_browser_width = advanced_ads_get_browser_width();
if ( previous_width === advanced_ads_browser_width ) {
// Return if the viewport has not actually changed
// Scroll events were triggering this on iOS due to the position of the address bar.
return;
}
advanced_ads_save_width( advanced_ads_browser_width );
var advanced_ads_responsive = window.advanced_ads_responsive || {};
if (
window.jQuery &&
parseInt( advanced_ads_responsive.reload_on_resize, 10 )
) {
jQuery( document ).triggerHandler( 'advanced-ads-resize-window' );
}
}, advanced_ads_resizetimeout );
}
// Save width in cookie.
function advanced_ads_save_width( width ) {
if ( window.advads === undefined ) {
return;
}
var cookieValue = advads.get_cookie( 'advanced_ads_visitor' );
var info = cookieValue ? JSON.parse( cookieValue ) : {};
info.browser_width = width;
advads.set_cookie(
'advanced_ads_visitor',
JSON.stringify( info ),
advanced_ads_cookieexpires,
advanced_ads_cookies.cookie_path,
advanced_ads_cookies.cookie_domain
);
}
// Create a listener calling only once after resize.
// http://stackoverflow.com/questions/2854407/javascript-jquery-window-resize-how-to-fire-after-the-resize-is-completed
var advads_resize_delay = ( function () {
var timer = 0;
return function ( callback, ms ) {
clearTimeout( timer );
timer = setTimeout( callback, ms );
};
} )();
/**
* Get the width of the browser.
*/
function advanced_ads_get_browser_width() {
if ( window.jQuery ) {
return jQuery( window ).width();
} else {
var browserWidth = 0;
if ( typeof window.innerWidth == 'number' ) {
// Non-IE
browserWidth = window.innerWidth;
} else if (
document.documentElement &&
document.documentElement.clientWidth
) {
// IE 6+ in 'standards compliant mode'
browserWidth = document.documentElement.clientWidth;
} else if ( document.body && document.body.clientWidth ) {
// IE 4 compatible
browserWidth = document.body.clientWidth;
}
return browserWidth;
}
}