Skip to content

Commit

Permalink
Merge branch 'prebid:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickloughrey authored Jun 21, 2024
2 parents 7faa5f7 + b92bff3 commit 6d3de5b
Show file tree
Hide file tree
Showing 53 changed files with 2,920 additions and 657 deletions.
1 change: 1 addition & 0 deletions integrationExamples/gpt/raynRtdProvider_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"3": ["264", "267", "261"],
"4": ["438"]
},
"103015": ['agdv23', 'avscg3'],
"903555595": {
"7": {
"2": ["51", "246"]
Expand Down
35 changes: 35 additions & 0 deletions libraries/adagioUtils/adagioUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
canAccessWindowTop,
generateUUID,
getWindowSelf,
getWindowTop,
isSafeFrameWindow
} from '../../src/utils.js';

/**
* Returns the best Window object to use with ADAGIO.
* @returns {Window} window.top or window.self object
*/
export function getBestWindowForAdagio() {
return (canAccessWindowTop()) ? getWindowTop() : getWindowSelf();
}

/**
* Returns the window.ADAGIO global object used to store Adagio data.
* This object is created in window.top if possible, otherwise in window.self.
*/
export const _ADAGIO = (function() {
const w = getBestWindowForAdagio();

w.ADAGIO = w.ADAGIO || {};
w.ADAGIO.pageviewId = w.ADAGIO.pageviewId || generateUUID();
w.ADAGIO.adUnits = w.ADAGIO.adUnits || {};
w.ADAGIO.pbjsAdUnits = w.ADAGIO.pbjsAdUnits || [];
w.ADAGIO.queue = w.ADAGIO.queue || [];
w.ADAGIO.versions = w.ADAGIO.versions || {};
w.ADAGIO.versions.pbjs = '$prebid.version$';
w.ADAGIO.windows = w.ADAGIO.windows || [];
w.ADAGIO.isSafeFrameWindow = isSafeFrameWindow();

return w.ADAGIO;
})();
1 change: 1 addition & 0 deletions libraries/appnexusUtils/anUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const appnexusAliases = [
{ code: 'adasta', gvlid: 32 },
{ code: 'beintoo', gvlid: 618 },
{ code: 'projectagora', gvlid: 1032 },
{ code: 'stailamedia', gvlid: 32 },
{ code: 'uol', gvlid: 32 },
{ code: 'adzymic', gvlid: 723 },
];
Expand Down
9 changes: 8 additions & 1 deletion libraries/autoplayDetection/autoplay.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ const autoplayVideoUrl =
'data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAADxtZGF0AAAAMGWIhAAV//73ye/Apuvb3rW/k89I/Cy3PsIqP39atohOSV14BYa1heKCYgALQC5K4QAAAwZtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAD6AABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACMHRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAEAAAAAAAAD6AAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAoAAAAFoAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAA+gAAAAAAAEAAAAAAahtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAEAAAABAAFXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAFTbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAABE3N0YmwAAACvc3RzZAAAAAAAAAABAAAAn2F2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAoABaAEgAAABIAAAAAAAAAAEVTGF2YzYwLjMxLjEwMiBsaWJ4MjY0AAAAAAAAAAAAAAAY//8AAAA1YXZjQwFkAAr/4QAYZ2QACqzZQo35IQAAAwABAAADAAIPEiWWAQAGaOvjyyLA/fj4AAAAABRidHJ0AAAAAAAAAaAAAAGgAAAAGHN0dHMAAAAAAAAAAQAAAAEAAEAAAAAAHHN0c2MAAAAAAAAAAQAAAAEAAAABAAAAAQAAABRzdHN6AAAAAAAAADQAAAABAAAAFHN0Y28AAAAAAAAAAQAAADAAAABidWR0YQAAAFptZXRhAAAAAAAAACFoZGxyAAAAAAAAAABtZGlyYXBwbAAAAAAAAAAAAAAAAC1pbHN0AAAAJal0b28AAAAdZGF0YQAAAAEAAAAATGF2ZjYwLjE2LjEwMA==';

function startDetection() {
const version = navigator.userAgent.match(/iPhone OS (\d+)_(\d+)/)
if (version !== null && parseInt(version[1]) < 17 && !navigator.userAgent.includes('Safari')) {
// skip autodetection on iOS 16 WebView
return
}

// we create an HTMLVideoElement muted and not displayed in which we try to play a one frame video
const videoElement = document.createElement('video');
videoElement.src = autoplayVideoUrl;
Expand All @@ -32,7 +38,8 @@ function startDetection() {
.play()
.then(() => {
autoplayEnabled = true;
videoElement.pause();
// if the video is played on a WebView with playsinline = false, this stops the video, to prevent it from being displayed fullscreen
videoElement.src = '';
})
.catch(() => {
autoplayEnabled = false;
Expand Down
1 change: 1 addition & 0 deletions modules/.submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"1plusXRtdProvider",
"a1MediaRtdProvider",
"aaxBlockmeterRtdProvider",
"adagioRtdProvider",
"adlooxRtdProvider",
"adnuntiusRtdProvider",
"airgridRtdProvider",
Expand Down
18 changes: 1 addition & 17 deletions modules/adagioBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ import {
generateUUID,
getDNT,
getWindowSelf,
getWindowTop,
isArray,
isArrayOfNums,
isFn,
isInteger,
isNumber,
isSafeFrameWindow,
isStr,
logError,
logInfo,
Expand All @@ -26,6 +24,7 @@ import { config } from '../src/config.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
import { find } from '../src/polyfill.js';
import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js';
import { _ADAGIO } from '../libraries/adagioUtils/adagioUtils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { userSync } from '../src/userSync.js';

Expand Down Expand Up @@ -78,21 +77,6 @@ export const ORTB_VIDEO_PARAMS = {
* Returns the window.ADAGIO global object used to store Adagio data.
* This object is created in window.top if possible, otherwise in window.self.
*/
const _ADAGIO = (function() {
const w = (canAccessWindowTop()) ? getWindowTop() : getWindowSelf();

w.ADAGIO = w.ADAGIO || {};
w.ADAGIO.pageviewId = w.ADAGIO.pageviewId || generateUUID();
w.ADAGIO.adUnits = w.ADAGIO.adUnits || {};
w.ADAGIO.pbjsAdUnits = w.ADAGIO.pbjsAdUnits || [];
w.ADAGIO.queue = w.ADAGIO.queue || [];
w.ADAGIO.versions = w.ADAGIO.versions || {};
w.ADAGIO.versions.pbjs = '$prebid.version$';
w.ADAGIO.isSafeFrameWindow = isSafeFrameWindow();

return w.ADAGIO;
})();

function getDevice() {
const language = navigator.language ? 'language' : 'userLanguage';
return {
Expand Down
92 changes: 41 additions & 51 deletions modules/adagioRtdProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
deepAccess,
deepSetValue,
generateUUID,
getDomLoadingDuration,
getSafeframeGeometry,
getUniqueIdentifierStr,
getWindowSelf,
getWindowTop,
Expand All @@ -24,6 +26,7 @@ import {
isStr,
prefixLog
} from '../src/utils.js';
import { _ADAGIO, getBestWindowForAdagio } from '../libraries/adagioUtils/adagioUtils.js';
import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js';

/**
Expand All @@ -35,30 +38,18 @@ const ADAGIO_BIDDER_CODE = 'adagio';
const GVLID = 617;
const SCRIPT_URL = 'https://script.4dex.io/a/latest/adagio.js';
const SESS_DURATION = 30 * 60 * 1000;
export const PLACEMENT_SOURCES = {
ORTB: 'ortb', // implicit default, not used atm.
ADUNITCODE: 'code',
GPID: 'gpid'
};
export const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME });

const { logError, logWarn } = prefixLog('AdagioRtdProvider:');

// Guard to avoid storing the same bid data several times.
const guard = new Set();

/**
* Returns the window.ADAGIO global object used to store Adagio data.
* This object is created in window.top if possible, otherwise in window.self.
*/
const _ADAGIO = (function() {
const w = (canAccessWindowTop()) ? getWindowTop() : getWindowSelf();

w.ADAGIO = w.ADAGIO || {};
w.ADAGIO.pageviewId = w.ADAGIO.pageviewId || generateUUID();
w.ADAGIO.adUnits = w.ADAGIO.adUnits || {};
w.ADAGIO.pbjsAdUnits = w.ADAGIO.pbjsAdUnits || [];
w.ADAGIO.queue = w.ADAGIO.queue || [];
w.ADAGIO.windows = w.ADAGIO.windows || [];

return w.ADAGIO;
})();

/**
* Store the sampling data.
* This data is used to determine if beacons should be sent to adagio.
Expand Down Expand Up @@ -131,12 +122,14 @@ const _FEATURES = (function() {
features.data = {};
},
get: function() {
const w = getBestWindowForAdagio();

if (!features.initialized) {
features.data = {
page_dimensions: getPageDimensions().toString(),
viewport_dimensions: getViewPortDimensions().toString(),
user_timestamp: getTimestampUTC().toString(),
dom_loading: getDomLoadingDuration().toString(),
dom_loading: getDomLoadingDuration(w).toString(),
};
features.initialized = true;
}
Expand Down Expand Up @@ -271,10 +264,12 @@ function onBidRequest(bidderRequest, config, _userConsent) {
* @param {*} config
*/
function onGetBidRequestData(bidReqConfig, callback, config) {
const configParams = deepAccess(config, 'params', {});
const { site: ortb2Site } = bidReqConfig.ortb2Fragments.global;
const features = _internal.getFeatures().get();
const ext = {
uid: generateUUID(),
pageviewId: _ADAGIO.pageviewId,
features: { ...features },
session: { ..._SESSION.get() }
};
Expand All @@ -294,8 +289,26 @@ function onGetBidRequestData(bidReqConfig, callback, config) {
const slotPosition = getSlotPosition(adUnit);
deepSetValue(ortb2Imp, `ext.data.adg_rtd.adunit_position`, slotPosition);

// We expect `pagetype` `category` are defined in FPD `ortb2.site.ext.data` object.
// `placement` is expected in FPD `adUnits[].ortb2Imp.ext.data` object. (Please note that this `placement` is not related to the oRTB video property.)
// It is expected that the publisher set a `adUnits[].ortb2Imp.ext.data.placement` value.
// Btw, We allow fallback sources to programmatically set this value.
// The source is defined in the `config.params.placementSource` and the possible values are `code` or `gpid`.
// (Please note that this `placement` is not related to the oRTB video property.)
if (!deepAccess(ortb2Imp, 'ext.data.placement')) {
const { placementSource = '' } = configParams;

switch (placementSource.toLowerCase()) {
case PLACEMENT_SOURCES.ADUNITCODE:
deepSetValue(ortb2Imp, 'ext.data.placement', adUnit.code);
break;
case PLACEMENT_SOURCES.GPID:
deepSetValue(ortb2Imp, 'ext.data.placement', deepAccess(ortb2Imp, 'ext.gpid'));
break;
default:
logWarn('`ortb2Imp.ext.data.placement` is missing and `params.definePlacement` is not set in the config.');
}
}

// We expect that `pagetype`, `category`, `placement` are defined in FPD `ortb2.site.ext.data` and `adUnits[].ortb2Imp.ext.data` objects.
// Btw, we have to ensure compatibility with publishers that use the "legacy" adagio params at the adUnit.params level.
const adagioBid = adUnit.bids.find(bid => _internal.isAdagioBidder(bid.bidder));
if (adagioBid) {
Expand All @@ -316,9 +329,6 @@ function onGetBidRequestData(bidReqConfig, callback, config) {
if (adagioBid.params.placement) {
deepSetValue(ortb2Imp, 'ext.data.placement', adagioBid.params.placement);
mustWarnOrtb2Imp = true;
} else {
// If the placement is not defined, we fallback to the adUnit code.
deepSetValue(ortb2Imp, 'ext.data.placement', adUnit.code);
}
}

Expand Down Expand Up @@ -428,16 +438,14 @@ function getSlotPosition(adUnit) {
const position = { x: 0, y: 0 };

if (isSafeFrameWindow()) {
const ws = getWindowSelf();

const sfGeom = (typeof ws.$sf.ext.geom === 'function') ? ws.$sf.ext.geom() : null;
const { self } = getSafeframeGeometry() || {};

if (!sfGeom || !sfGeom.self) {
if (!self) {
return '';
}

position.x = Math.round(sfGeom.self.t);
position.y = Math.round(sfGeom.self.l);
position.x = Math.round(self.t);
position.y = Math.round(self.l);
} else {
try {
// window.top based computing
Expand Down Expand Up @@ -513,16 +521,14 @@ function getViewPortDimensions() {
const viewportDims = { w: 0, h: 0 };

if (isSafeFrameWindow()) {
const ws = getWindowSelf();
const { win } = getSafeframeGeometry() || {};

const sfGeom = (typeof ws.$sf.ext.geom === 'function') ? ws.$sf.ext.geom() : null;

if (!sfGeom || !sfGeom.win) {
if (!win) {
return '';
}

viewportDims.w = Math.round(sfGeom.win.w);
viewportDims.h = Math.round(sfGeom.win.h);
viewportDims.w = Math.round(win.w);
viewportDims.h = Math.round(win.h);
} else {
// window.top based computing
const wt = getWindowTop();
Expand All @@ -538,22 +544,6 @@ function getTimestampUTC() {
return Math.floor(new Date().getTime() / 1000) - new Date().getTimezoneOffset() * 60;
}

function getDomLoadingDuration() {
const w = (canAccessWindowTop()) ? getWindowTop() : getWindowSelf();
const performance = w.performance;

let domLoadingDuration = -1;

if (performance && performance.timing && performance.timing.navigationStart > 0) {
const val = performance.timing.domLoading - performance.timing.navigationStart;
if (val > 0) {
domLoadingDuration = val;
}
}

return domLoadingDuration;
}

/**
* registerEventsForAdServers bind adagio listeners to ad-server events.
* Theses events are used to track the viewability and attention.
Expand Down
1 change: 1 addition & 0 deletions modules/adagioRtdProvider.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pbjs.setConfig({
params: {
organizationId: '1000' // Required. Provided by Adagio
site: 'my-site' // Required. Provided by Adagio
placementSource: 'ortb' // Optional. Where to find the "placement" value. Possible values: 'ortb'<default> | 'code' | 'gpid'
}
}]
}
Expand Down
34 changes: 3 additions & 31 deletions modules/bliinkBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { registerBidder } from '../src/adapters/bidderFactory.js'
import { config } from '../src/config.js'
import { _each, deepAccess, deepSetValue, getWindowSelf, getWindowTop } from '../src/utils.js'
import { _each, canAccessWindowTop, deepAccess, deepSetValue, getDomLoadingDuration, getWindowSelf, getWindowTop } from '../src/utils.js'
export const BIDDER_CODE = 'bliink'
export const GVL_ID = 658
export const BLIINK_ENDPOINT_ENGINE = 'https://engine.bliink.io/prebid'
Expand Down Expand Up @@ -121,35 +121,6 @@ export function getKeywords() {
return [];
}

function canAccessTopWindow() {
try {
if (getWindowTop().location.href) {
return true;
}
} catch (error) {
return false;
}
}

/**
* domLoading feature is computed on window.top if reachable.
*/
export function getDomLoadingDuration() {
let domLoadingDuration = -1;
let performance;

performance = (canAccessTopWindow()) ? getWindowTop().performance : getWindowSelf().performance;

if (performance && performance.timing && performance.timing.navigationStart > 0) {
const val = performance.timing.domLoading - performance.timing.navigationStart;
if (val > 0) {
domLoadingDuration = val;
}
}

return domLoadingDuration;
}

/**
* @param bidResponse
* @return {({cpm, netRevenue: boolean, requestId, width: number, currency, ttl: number, creativeId, height: number}&{mediaType: string, vastXml})|null}
Expand Down Expand Up @@ -208,7 +179,8 @@ export const isBidRequestValid = (bid) => {
*/
export const buildRequests = (validBidRequests, bidderRequest) => {
if (!validBidRequests || !bidderRequest || !bidderRequest.bids) return null
const domLoadingDuration = getDomLoadingDuration().toString();
const w = (canAccessWindowTop()) ? getWindowTop() : getWindowSelf();
const domLoadingDuration = getDomLoadingDuration(w).toString();
const tags = bidderRequest.bids.map((bid) => {
let bidFloor;
const sizes = bid.sizes.map((size) => ({ w: size[0], h: size[1] }));
Expand Down
2 changes: 1 addition & 1 deletion modules/ceeIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const ceeIdSubmodule = {
* performs action to obtain id and return a value
* @function
* @returns {(IdResponse|undefined)}
*/
*/
getId(config) {
const { params = {} } = config;
const { tokenName, value } = params
Expand Down
2 changes: 1 addition & 1 deletion modules/dailymotionBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function getVideoMetadata(bidRequest, bidderRequest) {
? videoParams.isCreatedForKids
: null,
context: {
siteOrAppCat: deepAccess(contentObj, 'cat', ''),
siteOrAppCat: deepAccess(contentObj, 'cat', []),
videoViewsInSession: (
typeof videoParams.videoViewsInSession === 'number' &&
videoParams.videoViewsInSession >= 0
Expand Down
Loading

0 comments on commit 6d3de5b

Please sign in to comment.