Skip to content

Commit

Permalink
Apester add support adset dats
Browse files Browse the repository at this point in the history
  • Loading branch information
andreyYatskov committed Feb 12, 2024
1 parent c401c63 commit ad51d6a
Show file tree
Hide file tree
Showing 12 changed files with 530 additions and 263 deletions.
5 changes: 3 additions & 2 deletions extensions/amp-apester-media/0.1/amp-apester-media.css
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@
.i-amphtml-amp-apester-in-unit {
display: block!important;
position: relative!important;
top: 50%!important;
transform: translateY(-50%)!important;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0!important;
}
2 changes: 2 additions & 0 deletions extensions/amp-apester-media/0.1/amp-apester-media.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {dev, user, userAssert} from '#utils/log';
import {handleAds} from './monetization';
import {
extractTags,
getOperatingSystem,
getPlatform,
registerEvent,
setFullscreenOff,
Expand Down Expand Up @@ -188,6 +189,7 @@ class AmpApesterMedia extends AMP.BaseElement {
const queryParams = {};
queryParams['renderer'] = false;
queryParams['platform'] = getPlatform();
queryParams['os'] = getOperatingSystem();
if (inative) {
if (idOrToken) {
suffix = `/inatives/${idOrToken}`;
Expand Down
246 changes: 246 additions & 0 deletions extensions/amp-apester-media/0.1/monetization/ads-constructor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
import {createElementWithAttributes} from '#core/dom';
import {setStyle} from '#core/dom/style';
import {Services} from '#service';

import {defaultRefreshTime, AD_TYPES, defaultBannerSizes} from './consent-util';

/**
* @param {!AmpElement} apesterElement
* @return {{height: number, width: number}}
*/
export function getCompanionVideoAdSize(apesterElement) {
const adWidth = apesterElement./*REVIEW*/ clientWidth;
const adRatio = 0.6;
const adHeight = Math.ceil(adWidth * adRatio);
return {width: adWidth, height: adHeight};
}

/**
* @param {!AmpElement} apesterElement
* @param {{height: number, width: number}} size
* @param {string} aniviewPlayerId
* @param {!JsonObject} consentObj
* @param {string} publisherId
* @return {!Element}
*/
export function getAniviewAdElement(apesterElement, size, aniviewPlayerId, consentObj, publisherId) {
publisherId = publisherId || '5fabb425e5d4cb4bbc0ca7e4';
const ampAvAd = createElementWithAttributes(
/** @type {!Document} */ (apesterElement.ownerDocument),
'amp-iframe',
{
'scrolling': 'no',
'id': 'amp-iframe',
'title': 'Ads',
'layout': 'responsive',
'sandbox': 'allow-scripts allow-same-origin allow-popups',
'allowfullscreen': 'false',
'frameborder': '0',
'width': size.width,
'height': size.height,
'src': `https://player.avplayer.com/amp/ampiframe.html?AV_TAGID=${aniviewPlayerId}&AV_PUBLISHERID=${publisherId}`,
}
);

if (consentObj?.gdpr) {
ampAvAd['data-av_gdpr'] = consentObj['gdpr'];
ampAvAd['data-av_consent'] = consentObj['user_consent'];
}
return ampAvAd;
}

/**
* @param {!AmpElement} apesterElement
* @param {string} aniviewPlayerId
* @param {!JsonObject} consentObj
* @param {boolean} isAbove
* @param {string} publisherId
* @return {!Element}
*/
export function constructStaticAniviewAd(apesterElement, aniviewPlayerId, consentObj, isAbove, publisherId) {
const size = getCompanionVideoAdSize(apesterElement);
const ampAvAd = getAniviewAdElement(apesterElement, size, aniviewPlayerId, consentObj, publisherId);

ampAvAd.classList.add('i-amphtml-amp-apester-companion');

apesterElement.parentNode.insertBefore(ampAvAd, isAbove ? apesterElement : apesterElement.nextSibling);

Services.mutatorForDoc(apesterElement).requestChangeSize(
ampAvAd,
size.height
);
}

/**
* @param {string} slot
* @param {Array} bannerSizes
* @param {!AmpElement} apesterElement
* @param {number} refreshInterval
* @param {!JsonObject} rtcConfig
* @param {!boolean} isAbove
* @return {!Element}
*/
export function constructStaticDisplayAd(
slot,
bannerSizes,
apesterElement,
refreshInterval,
rtcConfig,
isAbove,
) {
const maxWidth = Math.max.apply(
null,
bannerSizes.map((s) => s[0])
);
const maxHeight = Math.max.apply(
null,
bannerSizes.map((s) => s[1])
);

const multiSizeData = bannerSizes.map((size) => size.join('x')).join();
const ampAd = createElementWithAttributes(
/** @type {!Document} */ (apesterElement.ownerDocument),
'amp-ad',
{
'width': `${maxWidth}`,
'height': `${maxHeight}`,
'type': 'doubleclick',
'layout': 'fixed',
'data-slot': `${slot}`,
'data-multi-size-validation': 'false',
'data-multi-size': multiSizeData,
'data-enable-refresh': `${refreshInterval}`,
}
);
if (rtcConfig) {
ampAd.setAttribute('rtc-config', JSON.stringify(rtcConfig));
}
ampAd.classList.add('i-amphtml-amp-apester-companion');
apesterElement.parentNode.insertBefore(ampAd, isAbove ? apesterElement : apesterElement.nextSibling);
Services.mutatorForDoc(apesterElement).requestChangeSize(
ampAd,
maxHeight,
/* newWidth */ undefined
);
return ampAd;
}

/**
* @param {string} slot
* @param {Array} bannerSizes
* @param {!AmpElement} apesterElement
* @param {!JsonObject} rtcConfig
* @return {!Element}
*/
export function constructBottomAd(
slot,
apesterElement,
rtcConfig
) {
const height = 50;
const ampAd = createElementWithAttributes(
/** @type {!Document} */ (apesterElement.ownerDocument),
'amp-ad',
{
'width': '300',
'height': `${height}`,
'type': 'doubleclick',
'layout': 'fixed',
'data-slot': `${slot}`,
'data-multi-size-validation': 'false',
'data-enable-refresh': `${defaultRefreshTime}`,
}
);
if (rtcConfig) {
ampAd.setAttribute('rtc-config', JSON.stringify(rtcConfig));
}
ampAd.classList.add('i-amphtml-amp-apester-bottom-ad');
apesterElement.appendChild(ampAd);
Services.mutatorForDoc(apesterElement).requestChangeSize(ampAd, height);
return ampAd;
}


/**
* @param {!AmpElement} adWrap
* @param {!AmpElement} progressBar
* @param {!JsonObject} refreshOptions
*/
function showInUnitAd(adWrap, progressBar, refreshOptions) {
const {skipTimer, timeInView} = refreshOptions;
const showTime = timeInView || skipTimer;
adWrap.classList.add('active');
setStyle(progressBar, 'animation', `progress ${showTime}s linear 1`);
const timer = setTimeout(() => {
adWrap.classList.remove('active');
clearTimeout(timer);
}, showTime * 1000);
}

/**
* @param {string} mediaType
* @param {string} aniviewPlayerIdOrAdUnit
* @param {!AmpElement} apesterElement
* @param {!JsonObject} consentObj
* @param {!JsonObject} refreshOptions
* @param {string} publisherId
* @param {!JsonObject} rtcConfig
*/
export function constructInUnitAd(mediaType, aniviewPlayerIdOrAdUnit, apesterElement, consentObj, refreshOptions, publisherId, rtcConfig) {
let size;
let ampAvAd;
const {skipTimer, timeout, timeInView, timeBetweenAds} = refreshOptions;
const refreshTime = ((timeBetweenAds || timeout || 20) + (timeInView || skipTimer)) * 1000;
if (mediaType === AD_TYPES.video) {
size = getCompanionVideoAdSize(apesterElement);
ampAvAd = getAniviewAdElement(apesterElement, size, aniviewPlayerIdOrAdUnit, consentObj, publisherId);
} else {
size = {width: 300, height: 250};
ampAvAd = createElementWithAttributes(
/** @type {!Document} */ (apesterElement.ownerDocument),
'amp-ad',
{
'width': `${size.width}`,
'height': `${size.height}`,
'type': 'doubleclick',
'layout': 'fixed',
'data-slot': `${aniviewPlayerIdOrAdUnit}`,
'data-multi-size-validation': 'false',
'data-enable-refresh': `${refreshTime}`,
}
);
if (rtcConfig) {
ampAd.setAttribute('rtc-config', JSON.stringify(rtcConfig));
}
}

ampAvAd.classList.add('i-amphtml-amp-apester-in-unit');

const ampAvAdWrap = createElementWithAttributes(
/** @type {!Document} */ (apesterElement.ownerDocument),
'div',
{'class': 'i-amphtml-amp-apester-in-unit-wrap'}
);

const progressBarWrap = createElementWithAttributes(
/** @type {!Document} */ (apesterElement.ownerDocument),
'div',
{'class': 'i-amphtml-amp-apester-progress-bar'}
);
ampAvAdWrap.appendChild(progressBarWrap);
ampAvAdWrap.appendChild(ampAvAd);
apesterElement.appendChild(ampAvAdWrap);

showInUnitAd(ampAvAdWrap, progressBarWrap, refreshOptions);
setInterval(
() => {
showInUnitAd(ampAvAdWrap, progressBarWrap, refreshOptions);
},
refreshTime
);

Services.mutatorForDoc(apesterElement).requestChangeSize(
ampAvAd,
size.height
);
}
81 changes: 81 additions & 0 deletions extensions/amp-apester-media/0.1/monetization/adset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import {getValueForExpr} from '#core/types/object';

import {
constructStaticDisplayAd,
constructStaticAniviewAd,
constructBottomAd,
constructInUnitAd
} from './ads-constructor';
import {PLACAMENT_POSITIONS, AD_TYPES, defaultBannerSizes, defaultRefreshTime} from './consent-util';


/**
* @param {!JsonObject} media
* @param {!AmpElement} apesterElement
* @param {!JsonObject} consentObj
*/
export function handleAdsetAds(media, apesterElement, consentObj) {
// check if adset settings is set
const adsetData = getValueForExpr(
/**@type {!JsonObject}*/ (media),
'adsetData'
);
const adsetPlacements = adsetData?.placements;
if (!adsetPlacements?.length) {
return;
}
const staticSettings = adsetData.settings?.staticAds || {};
const inUnitSettings = adsetData.settings?.inUnit || {};

adsetPlacements.forEach((adPlacement) => {
const adData = adPlacement.ads[0];
const adProvider = adData?.provider;
const adUnit = adProvider?.adUnit;
const aniviewPlayerId = adProvider?.playerId;
const rtcConfig = adProvider?.rtcConfig;

// static ads above or below
if ([PLACAMENT_POSITIONS.above, PLACAMENT_POSITIONS.below].includes(adPlacement.type)) {
const isAbove = adPlacement.type === PLACAMENT_POSITIONS.above;

if (adUnit && adData.mediaType === AD_TYPES.display) {
const refreshInterval = staticSettings?.refresh?.refreshTime || defaultRefreshTime;
const bannerSizes = adProvider.sizes || defaultBannerSizes;
constructStaticDisplayAd(
adUnit,
bannerSizes,
apesterElement,
refreshInterval,
rtcConfig,
isAbove
);
} else if (aniviewPlayerId && adData.mediaType === AD_TYPES.video) {
constructStaticAniviewAd(
apesterElement,
aniviewPlayerId,
consentObj,
isAbove,
adProvider?.publisherId
);
}
}

// bottom Ad
if (adPlacement.type === PLACAMENT_POSITIONS.bottom && adUnit) {
constructBottomAd(adUnit, apesterElement, rtcConfig);
}

// inUnit Ad
if (adPlacement.type === PLACAMENT_POSITIONS.in_unit && (adUnit || aniviewPlayerId)) {
constructInUnitAd(
adData.mediaType,
adData.mediaType === AD_TYPES.display ? adUnit : aniviewPlayerId,
apesterElement,
consentObj,
inUnitSettings,
adProvider?.publisherId,
rtcConfig
);
}
});
}
Loading

0 comments on commit ad51d6a

Please sign in to comment.