@astro-eco/dynamic-ads
Version:
> This library helps to create ads placeholder and render ads dynamically in the DOM.
991 lines (866 loc) • 32.6 kB
JavaScript
window.pbjs = window.pbjs || { cmd: [] };
window.googletag = window.googletag || { cmd: [] };
window.__ADS_CONFIG_ENDPOINT__ = window.__ADS_CONFIG_ENDPOINT__;
window.__USERID__ = window.__USERID__;
window.adSlots = [];
window.__DA_CONFIG__ = {
missedAds: [],
ads: [],
pageAds: [],
global: {}
}
let adTargets = null;
const TIMEOUT = 5000;
const breakPointMobile = window.__BREAK_POINT_MOBILE__ || '600px';
const breakPointTablet = window.__BREAK_POINT_TABLET__ || '960px';
const FAILSAFE_TIMEOUT = 3500;
const dynamicads = (() => {
// Public Method
const _init = async () => {
const searchParams = new URLSearchParams(window.location.search);
const disableDynamicAds = searchParams.get('disableDynamicAds');
const fallbackAds = searchParams.get('fallbackAds');
const enableDynamicAds = searchParams.get('enableDynamicAds');
if ((disableDynamicAds && disableDynamicAds === 'true') || (fallbackAds && fallbackAds ==='true')) {
return;
}
const configEndpoint = __ADS_CONFIG_ENDPOINT__;
if (!configEndpoint) return;
const { ads, global } = await _getConfiguration(configEndpoint);
if (global && global.disableDynamicAdsLibrary) {
if(!enableDynamicAds) {
return;
}
}
if (!ads) {
return;
}
if (ads && ads.length === 0) {
return;
}
__DA_CONFIG__.ads = ads;
__DA_CONFIG__.global = global;
const pageAds = _getPageAds();
__DA_CONFIG__.pageAds = pageAds;
_renderAds();
const dynamicAdsConsole = searchParams.get('dynamicAdsConsole');
if (dynamicAdsConsole && dynamicAdsConsole === 'true') {
_openConsole();
}
};
const _openConsole = () => {
const consoleWrapper = _createElement('div');
consoleWrapper.id = 'ad-console-wrapper';
consoleWrapper.setAttribute('style', 'background: black; position: fixed; top: 10px; right: 10px; z-index: 9999; width: 25%; height: 500px; overflow: auto;');
const consoleBar = _createElement('div');
consoleBar.id = 'ad-console-wrapper-bar';
consoleBar.setAttribute('style', 'position: fixed; width: 24%;background: #cfcfcf;padding: 0 0 0 10px;color: #fff;display: flex;');
const consoleTitle = _createElement('div');
consoleTitle.id = 'ad-console-wrapper-title';
consoleTitle.innerHTML = 'Ad Console';
consoleTitle.setAttribute('style', 'flex: 1');
const consoleClose = _createElement('a');
consoleClose.id = 'ad-console-wrapper-close';
consoleClose.innerHTML = 'close';
consoleClose.setAttribute('style', 'flex: 1;text-align: end;cursor: pointer;flex-grow: 0;');
consoleClose.addEventListener('click', () =>{
const wrapper = document.getElementById('ad-console-wrapper')
if (wrapper && wrapper.remove) {
wrapper.remove();
}
});
const consoleContent = _createElement('div');
consoleContent.id = 'ad-console-wrapper-content';
consoleContent.setAttribute('style', 'color: #cfcfcf; padding: 10px');
consoleBar.appendChild(consoleTitle);
consoleBar.appendChild(consoleClose);
consoleWrapper.appendChild(consoleBar);
consoleWrapper.appendChild(consoleContent);
document.body.appendChild(consoleWrapper);
}
const _insertElement = (
referenceNode,
insertBefore,
insertAfter,
insertInside,
adConfig,
isOutOfPageSlot = false
) => {
let elementInserted = false;
if (!referenceNode || !adConfig) {
return elementInserted;
}
const { beforeEl, afterEl, insideEl } = _createNewElement(
adConfig,
isOutOfPageSlot
);
const parentElement = referenceNode.parentNode;
const eleIndex = Array.prototype.indexOf.call(
parentElement.children,
referenceNode,
);
if (insertBefore) {
parentElement.insertBefore(beforeEl, parentElement.children[eleIndex]);
elementInserted = true;
}
if (insertAfter) {
parentElement.insertBefore(
afterEl,
parentElement.children[eleIndex].nextSibling,
);
elementInserted = true;
}
if (insertInside) {
referenceNode.appendChild(insideEl);
elementInserted = true;
}
return elementInserted;
};
const _createElement = type => document.createElement(type).cloneNode(true);
const _getInterstitialWrapper = closeBtnTitle => {
const interstitialWrapper = _createElement('div');
interstitialWrapper.id = 'interstitial-popup';
interstitialWrapper.classList.add(`interstitial-popup`);
interstitialWrapper.setAttribute('style', 'display: none;');
const interstitialButton = _createElement('button');
interstitialButton.classList.add(`interstitial-button`);
interstitialButton.innerHTML = closeBtnTitle || 'Close';
interstitialButton.onclick = () => {
const interstitialAd = document.querySelector('.interstitial-popup');
if (interstitialAd && interstitialAd.remove) {
interstitialAd.remove();
}
};
interstitialWrapper.appendChild(interstitialButton);
return interstitialWrapper;
};
const _getOutOfPageElement = (divId, type) => {
const ele = _createElement('div');
ele.id = divId;
ele.classList.add(`ad-slot-oop`);
ele.setAttribute('data-dynamic-ad', 'ADOOPSLOT');
ele.setAttribute('data-ad-type', type);
return ele;
};
const _createOutOfPageElement = adConfig => {
const { divId, type, closeBtnTitle } = adConfig;
let ele = null;
if (type === 'interstitial') {
ele = _getInterstitialWrapper(closeBtnTitle);
const oopEle = _getOutOfPageElement(divId, type);
ele.appendChild(oopEle);
} else {
ele = _getOutOfPageElement(divId, type);
}
const adContainer = _createAdContainer();
adContainer.setAttribute('data-dynamic-ad', 'ADCONTAINER');
adContainer.setAttribute('data-dynamic-ad-type', type);
adContainer.appendChild(ele);
document.body.appendChild(adContainer);
return true;
};
const _createNewElement = (adConfig, isOutOfPageSlot) => {
const { containerStyles: adContainerStyles, divId, adsTitle } = adConfig;
const { containerStyles, defaultAdsTitle } = __DA_CONFIG__.global;
let styles = {};
if(!isOutOfPageSlot) {
const { isMobileScreen, isTabletScreen, isDesktopScreen } = _getLayout();
const { desktop = {}, mobile = {}, tablet = {} } = adContainerStyles ? adContainerStyles : containerStyles;
styles = {
...styles,
...(isMobileScreen && mobile),
...(isTabletScreen && tablet),
...(isDesktopScreen && desktop),
};
}
let adTitle = null;
if(!isOutOfPageSlot) {
adTitle = _createElement('div');
adTitle.classList.add(`ad-container-title`);
adTitle.innerHTML = adsTitle ? adsTitle : defaultAdsTitle;
}
const beforeAdContainer = _createAdContainer();
beforeAdContainer.classList.add(`ad-container-before`);
if (Object.keys(styles).length) {
beforeAdContainer.setAttribute(
'style',
Object.keys(styles)
.map(key => `${key}:${styles[key]}`)
.join(';'),
);
}
beforeAdContainer.setAttribute('data-dynamic-ad', 'ADCONTAINER');
const afterAdContainer = _createAdContainer();
afterAdContainer.classList.add(`ad-container-after`);
if (Object.keys(styles).length) {
afterAdContainer.setAttribute(
'style',
Object.keys(styles)
.map(key => `${key}:${styles[key]}`)
.join(';'),
);
}
afterAdContainer.setAttribute('data-dynamic-ad', 'ADCONTAINER');
const insideAdContainer = _createAdContainer();
insideAdContainer.classList.add(`ad-container-inside`);
if (Object.keys(styles).length) {
insideAdContainer.setAttribute(
'style',
Object.keys(styles)
.map(key => `${key}:${styles[key]}`)
.join(';'),
);
}
afterAdContainer.setAttribute('data-dynamic-ad', 'ADCONTAINER');
const beforeEle = _createElement('div');
beforeEle.id = divId;
beforeEle.classList.add(`ad-slot-before`);
beforeEle.setAttribute('data-dynamic-ad', 'ADSLOT');
if(adTitle) beforeAdContainer.appendChild(adTitle.cloneNode(true));
beforeAdContainer.appendChild(beforeEle);
const afterEle = _createElement('div');
afterEle.id = divId;
afterEle.classList.add(`ad-slot-after`);
afterEle.setAttribute('data-dynamic-ad', 'ADSLOT');
if(adTitle) afterAdContainer.appendChild(adTitle.cloneNode(true));
afterAdContainer.appendChild(afterEle);
const insideEle = _createElement('div');
insideEle.id = divId;
insideEle.classList.add(`ad-slot-inside`);
insideEle.setAttribute('data-dynamic-ad', 'ADSLOT');
if(adTitle) insideAdContainer.appendChild(adTitle.cloneNode(true));
insideAdContainer.appendChild(insideEle);
return {
beforeEl: beforeAdContainer,
afterEl: afterAdContainer,
insideEl: insideAdContainer
};
};
const _createAdContainer = () => {
const adsContainer = _createElement('div');
adsContainer.classList.add('ads-container');
return adsContainer.cloneNode(true);
};
const _transformConfig = config => {
const obj = {};
config.forEach(i => {
const { key, value } = i;
obj[key] = value;
});
return obj;
};
const _getConfiguration = async configEndpoint => {
const response = await fetch(configEndpoint);
const data = await response.json();
return _transformConfig(data.response.config);
};
const _renderAds = (pageAdsConfig = null) => {
const pageAds = pageAdsConfig ? pageAdsConfig : __DA_CONFIG__.pageAds;
if(pageAds && pageAds.length === 0) {
return;
}
const { lazyLoading, collapseEmptyDiv, setTargeting, demandManager } = __DA_CONFIG__.global;
googletag.cmd.push(() => {
// key value targetting
if(setTargeting) {
_addPageLeveltargets();
}
if(demandManager) {
googletag.pubads().disableInitialLoad();
}
let slot = '';
const headerBiddingSlots = [];
pageAds.forEach(adItem => {
const { pageLinkPlaceholder, divId, isOutOfPageSlot, type } = adItem;
if (_isSlotAlreadyExist(divId)) {
return null;
}
const { isMobileScreen, isDesktopScreen } = _getLayout();
const { selector: eleSelector, insertBefore: eleInsertBefore, insertAfter: eleInsertAfter, insertInside: eleInsertInside, mobile, desktop } = pageLinkPlaceholder;
let selector = null;
let insertBefore, insertAfter, insertInside;
insertBefore = insertAfter = insertInside = false;
if(!eleSelector) {
if(mobile && isMobileScreen) {
selector = mobile.selector;
insertBefore = mobile.insertBefore;
insertAfter = mobile.insertAfter;
insertInside = mobile.insertInside;
} else if(desktop && isDesktopScreen) {
selector = desktop.selector;
insertBefore = desktop.insertBefore;
insertAfter = desktop.insertAfter;
insertInside = desktop.insertInside;
}
} else {
selector = eleSelector;
insertBefore = eleInsertBefore;
insertAfter = eleInsertAfter;
insertInside = eleInsertInside;
if(mobile && isMobileScreen) {
selector = mobile.selector;
insertBefore = mobile.insertBefore;
insertAfter = mobile.insertAfter;
insertInside = mobile.insertInside;
} else if(desktop && isDesktopScreen) {
selector = desktop.selector;
insertBefore = desktop.insertBefore;
insertAfter = desktop.insertAfter;
insertInside = desktop.insertInside;
}
}
const selectedElement = document.querySelector(selector);
let slotInserted = false;
if (isOutOfPageSlot) {
if (selector) {
slotInserted = _insertElement(
selectedElement,
insertBefore,
insertAfter,
insertInside,
adItem,
isOutOfPageSlot
);
} else {
slotInserted = _createOutOfPageElement(adItem);
}
} else {
slotInserted = _insertElement(
selectedElement,
insertBefore,
insertAfter,
insertInside,
adItem,
);
}
if(!selectedElement && !slotInserted) {
if(__DA_CONFIG__.missedAds.findIndex(ele => ele.divId === adItem.divId) === -1) {
__DA_CONFIG__.missedAds.push(adItem);
}
return;
}
if (slotInserted) {
let adsDefinedSizeMapping = [];
let adSizes = [];
if (adItem.adSizeMapping) {
adsDefinedSizeMapping = _getDefinedSizeMapping(
adItem.adSizeMapping,
);
} else {
adSizes = _getAdSizes(adItem.sizeMapping);
}
const slotId = `Slot - ${divId}`;
if (
isOutOfPageSlot &&
(!adItem.sizeMapping && !adItem.adSizeMapping)
) {
slot = googletag.defineOutOfPageSlot(adItem.adUnitId, divId);
} else {
slot = googletag.defineSlot(
adItem.adUnitId,
adItem.adSizeMapping
? adsDefinedSizeMapping
: adSizes.reduce((acc, item) => {
acc = acc.concat(item[1]);
return acc;
}, []),
divId,
);
}
if (slot) {
if (isOutOfPageSlot || adItem.adSizeMapping) {
slot.addService(googletag.pubads());
} else {
slot.defineSizeMapping(adSizes).addService(googletag.pubads());
}
}
window.adSlots[slotId] = slot;
headerBiddingSlots.push(slot);
_adEvents(divId, adItem.adUnitId, type);
if(type === 'interstitial') {
googletag.pubads().addEventListener('slotRenderEnded', event => {
const slotId = event.slot.getSlotElementId();
if (!event.isEmpty && type === 'interstitial' && slotId === divId) {
const interstitialPopup = document.querySelector(
'.interstitial-popup',
);
interstitialPopup.setAttribute('style', 'display: block;');
}
});
}
}
});
if (lazyLoading && lazyLoading.enable) {
const { params } = lazyLoading;
googletag.pubads().enableLazyLoad(params);
}
if(collapseEmptyDiv) {
googletag.pubads().collapseEmptyDivs();
}
// // Enable SRA and services.
googletag.pubads().enableSingleRequest();
googletag.enableServices();
if(demandManager) {
// group any header bidding slots in an array
// make a request to DM to start header bidding
_demandManagerRequest(headerBiddingSlots);
}
googletag.display(slot);
});
};
const _adEvents = (divId, path, type) => {
const USERID = window.__USERID__ || '';
const { isMobileScreen, isTabletScreen } = _getLayout();
let deviceScreen;
if (isMobileScreen) {
deviceScreen = 'Mobile';
} else if (isTabletScreen) {
deviceScreen = 'Tablet';
} else {
deviceScreen = 'Desktop';
}
const timestamp = Date.now().toString();
if (googletag && googletag.apiReady) {
// This listener will be called when an impression is considered viewable.
googletag.pubads().addEventListener('impressionViewable', event => {
const slotId = event.slot.getSlotElementId();
if (slotId === divId) {
window &&
window.dataLayer &&
window.dataLayer.push({
event: 'GA_ADS',
adUnit: path,
divId,
device: deviceScreen,
timestamp,
userId: USERID,
adEventListener: 'impressionViewable',
adEventMessage: `Impression has become viewable for slot : ${slotId}`,
});
const consoleContentContainer = document.getElementById('ad-console-wrapper-content');
if(consoleContentContainer) {
const paragraph = _createElement("p");
paragraph.textContent = `Impression has become viewable for ${slotId}`;
consoleContentContainer.appendChild(paragraph);
}
}
});
// This listener will be called when a slot's creative iframe load event
// fires.
googletag.pubads().addEventListener('slotOnload', event => {
const slotId = event.slot.getSlotElementId();
if (slotId === divId) {
window &&
window.dataLayer &&
window.dataLayer.push({
event: 'GA_ADS',
adUnit: path,
divId,
device: deviceScreen,
timestamp,
userId: USERID,
adEventListener: 'slotOnload',
adEventMessage: `Creative iframe load event has fired : ${slotId}`,
});
_updateLazyLoadSlotStatus(slotId, "rendered");
const consoleContentContainer = document.getElementById('ad-console-wrapper-content')
if(consoleContentContainer) {
const paragraph = _createElement("p");
paragraph.textContent = `Creative iframe load event has fired ${slotId}`;
consoleContentContainer.appendChild(paragraph);
}
}
});
// This listener will be called when a slot has finished rendering.
googletag.pubads().addEventListener('slotRenderEnded', event => {
const slotId = event.slot.getSlotElementId();
if (slotId === divId) {
// Record details of the rendered ad.
const details = {
'Advertiser ID': event.advertiserId,
'Campaign ID': event.campaignId,
'Company IDs': event.companyIds,
'Creative ID': event.creativeId,
'Creative Template ID': event.creativeId,
'Is backfill?': event.isBackfill,
'Is empty?': event.isEmpty,
'Label IDs': event.labelIds,
'Line Item ID': event.lineItemId,
Size: event.size,
'Slot content changed?': event.slotContentChanged,
'Source Agnostic Creative ID': event.sourceAgnosticCreativeId,
'Source Agnostic Line Item ID': event.sourceAgnosticLineItemId,
'Yield Group IDs': event.yieldGroupIds,
};
window &&
window.dataLayer &&
window.dataLayer.push({
event: 'GA_ADS',
adUnit: path,
divId,
device: deviceScreen,
timestamp,
userId: USERID,
adEventListener: 'slotRenderEnded',
adEventMessage: `Slot has finished rendering : ${slotId}`,
adEventDetails: details,
});
const consoleContentContainer = document.getElementById('ad-console-wrapper-content')
if(consoleContentContainer) {
const paragraph = _createElement("p");
paragraph.textContent = `Slot has finished rendering ${slotId}`;
consoleContentContainer.appendChild(paragraph);
const pre = _createElement("pre");
const data_stringified = JSON.stringify(details, null, 2);
pre.innerHTML = data_stringified;
consoleContentContainer.appendChild(pre);
}
}
});
// This listener will be called when the specified service actually
// sets an ad request for a slot. Each slot will fire this event, even
// though they may be batched together in a single request if single
// request architecture (SRA) is enabled.
googletag.pubads().addEventListener('slotRequested', event => {
const slotId = event.slot.getSlotElementId();
if (slotId === divId) {
window &&
window.dataLayer &&
window.dataLayer.push({
event: 'GA_ADS',
adUnit: path,
divId,
device: deviceScreen,
timestamp,
userId: USERID,
adEventListener: 'slotRequested',
adEventMessage: `Slot has been requested : ${slotId}`,
});
_updateLazyLoadSlotStatus(slotId, "fetched");
const consoleContentContainer = document.getElementById('ad-console-wrapper-content')
if(consoleContentContainer) {
const paragraph = _createElement("p");
paragraph.textContent = `Slot has been requested ${slotId}`;
consoleContentContainer.appendChild(paragraph);
}
}
});
// This listener will be called when an ad response has been received for
// a slot.
googletag.pubads().addEventListener('slotResponseReceived', event => {
const slotId = event.slot.getSlotElementId();
if (slotId === divId) {
window &&
window.dataLayer &&
window.dataLayer.push({
event: 'GA_ADS',
adUnit: path,
divId,
device: deviceScreen,
timestamp,
userId: USERID,
adEventListener: 'slotResponseReceived',
adEventMessage: `Ad response has been received : ${slotId}`,
});
const consoleContentContainer = document.getElementById('ad-console-wrapper-content')
if(consoleContentContainer) {
const paragraph = _createElement("p");
paragraph.textContent = `Ad response has been received ${slotId}`;
consoleContentContainer.appendChild(paragraph);
}
}
});
}
};
const _destroyAllSlots = () => {
if (googletag.pubadsReady) {
googletag.cmd.push(() => {
googletag.destroySlots();
window.adSlots = [];
});
}
// additionally remove all the ad slots from the dom
const ALL_AD_SLOTS = document.querySelectorAll(
'[data-dynamic-ad="ADCONTAINER"]',
);
ALL_AD_SLOTS.forEach(e => {
e.remove();
});
const interstitialAd = document.querySelector('.interstitial-popup');
if (interstitialAd && interstitialAd.remove) {
interstitialAd.remove();
}
};
const _getPageAds = () => {
const path = window.location.pathname;
const pathName = path && path.toLowerCase();
const AdvertisementConfigs = [];
if (__DA_CONFIG__.ads && Array.isArray(__DA_CONFIG__.ads)) {
__DA_CONFIG__.ads.forEach(item => {
if (item.enabled) {
const { isMobileScreen, isDesktopScreen } = _getLayout();
const { showOnMobile, showOnDesktop } = item;
if (
(!showOnDesktop && !showOnMobile) ||
showOnMobile === isMobileScreen ||
showOnDesktop === isDesktopScreen
) {
item.routes.forEach(lp => {
const { link } = lp;
if (link && Array.isArray(link)) {
if(link.includes(pathName)) {
AdvertisementConfigs.push({ ...item, pageLinkPlaceholder: lp });
}
} else {
const pattern = new RegExp(`${link}$`);
if (pattern.test(pathName)) {
AdvertisementConfigs.push({ ...item, pageLinkPlaceholder: lp });
}
}
});
}
}
});
}
return AdvertisementConfigs;
};
const _getAdSizes = sizeMapping => {
let definedMapping = [];
const allSizes = [];
if (sizeMapping && googletag.sizeMapping) {
/* eslint-disable array-callback-return */
// mapping = googletag.sizeMapping();
definedMapping = googletag.sizeMapping();
const mobileSizeAdSizes = [];
const tabletSizeAdSizes = [];
const desktopSizeAdSizes = [];
Object.keys(sizeMapping).map(keys => {
const width = parseInt(sizeMapping[keys].split(',')[0], 10);
const height = parseInt(sizeMapping[keys].split(',')[1], 10);
if (keys < 600 && window.innerWidth >= width) {
mobileSizeAdSizes.push([width, height]);
} else if (keys < 960 && window.innerWidth >= width) {
tabletSizeAdSizes.push([width, height]);
} else if (window.innerWidth >= width) {
desktopSizeAdSizes.push([width, height]);
}
allSizes.push({ width, height });
// mapping.addSize([parseInt(keys, 10), height], [width, height]);
});
// size mapping will be only 3 dimensions
// 0 - 599, 600 - 959, 960 - infinity
// as a specific range will accept mutiple dimension options
// so it can cover more advertisement impressions
if (mobileSizeAdSizes.length) {
definedMapping.addSize(
// 0 - 599
[0, 10],
mobileSizeAdSizes,
);
} else {
definedMapping.addSize(
// 0 - 599
[0, 10],
_getFallbackSizeMaping(allSizes),
);
}
if (tabletSizeAdSizes.length) {
definedMapping.addSize(
// 600 - 959
[599, 10],
tabletSizeAdSizes,
);
} else {
definedMapping.addSize(
// 0 - 599
[599, 10],
_getFallbackSizeMaping(allSizes),
);
}
if (desktopSizeAdSizes.length) {
definedMapping.addSize(
// 960 - infinity
[959, 10],
desktopSizeAdSizes,
);
} else {
definedMapping.addSize(
// 0 - 599
[959, 10],
_getFallbackSizeMaping(allSizes),
);
}
definedMapping = definedMapping.build();
// mapping = mapping.build();
// console.log('mapping', definedMapping);
}
return definedMapping;
};
const _getDefinedSizeMapping = sizeMapping => {
let definedMapping = [];
if (sizeMapping) {
const { isMobileScreen, isTabletScreen, isDesktopScreen } = _getLayout();
if (isMobileScreen) {
const { mobile } = sizeMapping;
definedMapping = _getParsedSize(mobile);
} else if (isTabletScreen) {
const { tablet } = sizeMapping;
definedMapping = _getParsedSize(tablet);
} else if (isDesktopScreen) {
const { desktop } = sizeMapping;
definedMapping = _getParsedSize(desktop);
}
}
return definedMapping;
};
const _getParsedSize = sizes =>
sizes.map(item => {
let temp = null;
if (item) {
const x = parseInt(item.split(',')[0], 10);
const y = parseInt(item.split(',')[1], 10);
temp = [x, y];
}
return temp;
});
const _getFallbackSizeMaping = allSizes =>
allSizes.reduce((acc, { width, height }) => {
if (window.innerWidth > width) {
acc.push([width, height]);
}
return acc;
}, []);
const _getLayout = () => {
const isMobileScreen = window.matchMedia(`(max-width: ${breakPointMobile})`)
.matches;
const isTabletScreen = window.matchMedia(
`(min-width: calc(${breakPointMobile} + 1px)) and (max-width: ${breakPointTablet})`,
).matches;
const isMobileAndTabletScreen = isMobileScreen || isTabletScreen;
const isDesktopScreen = window.matchMedia(
`(min-width: calc(${breakPointTablet} + 1px))`,
).matches;
return {
isMobileScreen,
isTabletScreen,
isMobileAndTabletScreen,
isDesktopScreen,
};
};
const _setTargetting = targets => {
adTargets = targets;
};
// action which refreshes all slots
const _refreshAllSlots = () => {
if (googletag.pubadsReady) {
googletag.cmd.push(() => {
googletag.pubads().refresh();
});
}
};
// Note: calling clear() removes any currently displayed ads
// and replaces them with blank content, leaving the slots intact so they
// can be repopulated later.
const _clearAllSlots = () => {
if (googletag.pubadsReady) {
googletag.cmd.push(() => {
googletag.pubads().clear();
});
}
};
const _updateLazyLoadSlotStatus = (slotId, state) => {
const searchParams = new URLSearchParams(window.location.search);
const lazyDebug = searchParams.get('lazy_debug');
if(lazyDebug && lazyDebug === 'true') {
console.info('SlotId: ', slotId, '|| Lazy load status:', state)
}
}
const _isSlotAlreadyExist = divId => {
let isExist = false;
if (googletag.pubadsReady) {
googletag.cmd.push(() => {
const existingSlots = googletag.pubads().getSlots();
const existingAd = existingSlots.find(ad => {
const adId = ad && ad.getSlotElementId ? ad.getSlotElementId() : '';
return adId === divId;
});
if (existingAd) {
isExist = true;
}
});
}
return isExist;
};
const _demandManagerRequest = (slots) => {
// provide failsafeHandler with callback function to fire when we want to make
// the ad server request, as well as headerBiddingSlots to use in case of failsafe
const sendAdServerRequest = failsafeHandler(slotsToRefresh => {
googletag.pubads().refresh(slotsToRefresh);
}, slots);
// request bids when PBJS is ready
pbjs.que.push(() => {
pbjs.rp.requestBids({
callback: sendAdServerRequest,
gptSlotObjects: slots,
});
});
// start the failsafe timeout
setTimeout(sendAdServerRequest, FAILSAFE_TIMEOUT);
// function that handles the failsafe using boolean logic per auction
function failsafeHandler(callback, initialSlots) {
let adserverRequestSent = false;
return bidsBackSlots => {
if (adserverRequestSent) return;
adserverRequestSent = true;
callback(bidsBackSlots || initialSlots);
};
}
}
const _addPageLeveltargets = () => {
if (googletag.apiReady) {
if (adTargets && adTargets.length) {
adTargets.forEach(target => {
if (target) {
googletag
.pubads()
.setTargeting(
target.key,
target.value && target.value.toLowerCase(),
);
}
});
}
}
}
return {
_init,
_getConfiguration,
_destroyAllSlots,
_setTargetting,
_refreshAllSlots,
_clearAllSlots,
_renderAds,
_getPageAds,
};
})();
if (typeof window !== 'undefined') {
window.addEventListener('load', () => {
__DA_CONFIG__.missedAds = __DA_CONFIG__.ads = __DA_CONFIG__.global = __DA_CONFIG__.pageAds = [];
dynamicads._init();
});
document.addEventListener('__ON_ROUTE_CHANGE__', () => {
dynamicads._destroyAllSlots();
__DA_CONFIG__.missedAds = [];
setTimeout(() => {
const pageAds = dynamicads._getPageAds();
__DA_CONFIG__.pageAds = pageAds;
dynamicads._renderAds(pageAds);
}, TIMEOUT);
});
document.addEventListener('__ON_LAYOUT_CHANGE__', () => {
dynamicads._renderAds(__DA_CONFIG__.missedAds);
});
} else {
console.log('Oops, `window` is not defined');
}
export default dynamicads;