prebid.js 7.31.0 → 7.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adlooxRtdProvider.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/aidemBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/alkimiBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/aolBidAdapter.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/appushBidAdapter.js +1 -0
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectIdSystem.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/holidBidAdapter.js +1 -0
- package/dist/id5IdSystem.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/jwplayerVideoProvider.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/medianetRtdProvider.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +126 -123
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/orbitsoftBidAdapter.js +1 -0
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/permutiveRtdProvider.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/taboolaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/uid2IdSystem.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldlabBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/integrationExamples/gpt/adloox.html +5 -0
- package/modules/adagioBidAdapter.js +0 -4
- package/modules/adagioBidAdapter.md +4 -22
- package/modules/adlooxAnalyticsAdapter.md +5 -3
- package/modules/adlooxRtdProvider.js +82 -278
- package/modules/adlooxRtdProvider.md +6 -6
- package/modules/aidemBidAdapter.js +4 -0
- package/modules/aidemBidAdapter.md +1 -0
- package/modules/alkimiBidAdapter.js +23 -6
- package/modules/aolBidAdapter.js +12 -0
- package/modules/appnexusBidAdapter.js +2 -2
- package/modules/appushBidAdapter.js +188 -0
- package/modules/appushBidAdapter.md +79 -0
- package/modules/asoBidAdapter.js +8 -5
- package/modules/confiantRtdProvider.js +1 -1
- package/modules/connectIdSystem.js +15 -1
- package/modules/feedadBidAdapter.js +7 -5
- package/modules/holidBidAdapter.js +170 -0
- package/modules/holidBidAdapter.md +36 -0
- package/modules/jwplayerVideoProvider.js +10 -3
- package/modules/kueezRtbBidAdapter.js +21 -8
- package/modules/medianetRtdProvider.js +4 -4
- package/modules/nexx360BidAdapter.js +5 -7
- package/modules/orbitsoftBidAdapter.js +150 -0
- package/modules/permutiveRtdProvider.js +1 -1
- package/modules/riseBidAdapter.js +2 -1
- package/modules/riseBidAdapter.md +2 -0
- package/modules/seedtagBidAdapter.js +12 -0
- package/modules/smartxBidAdapter.js +6 -0
- package/modules/taboolaBidAdapter.js +61 -14
- package/modules/yahoosspBidAdapter.js +5 -0
- package/modules/yieldlabBidAdapter.js +150 -134
- package/modules/yieldmoBidAdapter.js +1 -12
- package/package.json +1 -1
- package/test/spec/modules/adagioBidAdapter_spec.js +1 -28
- package/test/spec/modules/adlooxRtdProvider_spec.js +28 -120
- package/test/spec/modules/aidemBidAdapter_spec.js +10 -2
- package/test/spec/modules/alkimiBidAdapter_spec.js +15 -3
- package/test/spec/modules/aolBidAdapter_spec.js +22 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +7 -3
- package/test/spec/modules/appushBidAdapter_spec.js +372 -0
- package/test/spec/modules/connectIdSystem_spec.js +17 -5
- package/test/spec/modules/feedadBidAdapter_spec.js +23 -1
- package/test/spec/modules/holidBidAdapter_spec.js +165 -0
- package/test/spec/modules/kueezRtbBidAdapter_spec.js +147 -24
- package/test/spec/modules/medianetRtdProvider_spec.js +3 -3
- package/test/spec/modules/orbitsoftBidAdapter_spec.js +255 -0
- package/test/spec/modules/riseBidAdapter_spec.js +7 -0
- package/test/spec/modules/seedtagBidAdapter_spec.js +56 -10
- package/test/spec/modules/smartxBidAdapter_spec.js +10 -0
- package/test/spec/modules/taboolaBidAdapter_spec.js +142 -5
- package/test/spec/modules/videoModule/submodules/jwplayerVideoProvider_spec.js +45 -10
- package/test/spec/modules/yahoosspBidAdapter_spec.js +16 -1
- package/test/spec/modules/yieldlabBidAdapter_spec.js +311 -301
- package/test/spec/modules/yieldmoBidAdapter_spec.js +70 -0
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
* @module modules/adlooxRtdProvider
|
|
7
7
|
* @requires module:modules/realTimeData
|
|
8
8
|
* @requires module:modules/adlooxAnalyticsAdapter
|
|
9
|
+
* @optional module:modules/intersectionRtdProvider
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
12
|
/* eslint standard/no-callback-literal: "off" */
|
|
12
13
|
/* eslint prebid/validate-imports: "off" */
|
|
13
14
|
|
|
15
|
+
import {auctionManager} from '../src/auctionManager.js';
|
|
14
16
|
import {command as analyticsCommand, COMMAND} from './adlooxAnalyticsAdapter.js';
|
|
15
17
|
import {submodule} from '../src/hook.js';
|
|
16
18
|
import {ajax} from '../src/ajax.js';
|
|
@@ -18,142 +20,31 @@ import {getGlobal} from '../src/prebidGlobal.js';
|
|
|
18
20
|
import {getRefererInfo} from '../src/refererDetection.js';
|
|
19
21
|
import {
|
|
20
22
|
_each,
|
|
23
|
+
_map,
|
|
24
|
+
buildUrl,
|
|
21
25
|
deepAccess,
|
|
26
|
+
deepClone,
|
|
22
27
|
deepSetValue,
|
|
23
|
-
getAdUnitSizes,
|
|
24
28
|
getGptSlotInfoForAdUnitCode,
|
|
25
29
|
isArray,
|
|
26
30
|
isBoolean,
|
|
27
31
|
isInteger,
|
|
28
32
|
isPlainObject,
|
|
29
|
-
isStr,
|
|
30
33
|
logError,
|
|
31
34
|
logInfo,
|
|
32
35
|
logWarn,
|
|
33
|
-
mergeDeep
|
|
36
|
+
mergeDeep,
|
|
37
|
+
parseUrl,
|
|
38
|
+
safeJSONParse
|
|
34
39
|
} from '../src/utils.js';
|
|
35
|
-
import {includes} from '../src/polyfill.js';
|
|
36
40
|
|
|
37
41
|
const MODULE_NAME = 'adloox';
|
|
38
42
|
const MODULE = `${MODULE_NAME}RtdProvider`;
|
|
39
43
|
|
|
40
44
|
const API_ORIGIN = 'https://p.adlooxtracking.com';
|
|
41
45
|
const SEGMENT_HISTORIC = { 'a': 'aud', 'd': 'dis', 'v': 'vid' };
|
|
42
|
-
const SEGMENT_HISTORIC_VALUES = Object.keys(SEGMENT_HISTORIC).map(k => SEGMENT_HISTORIC[k]);
|
|
43
46
|
|
|
44
|
-
const ADSERVER_TARGETING_PREFIX = '
|
|
45
|
-
|
|
46
|
-
const CREATIVE_WIDTH_MIN = 20;
|
|
47
|
-
const CREATIVE_HEIGHT_MIN = 20;
|
|
48
|
-
const CREATIVE_AREA_MIN = CREATIVE_WIDTH_MIN * CREATIVE_HEIGHT_MIN;
|
|
49
|
-
// try to avoid using IntersectionObserver as it has unbounded (observed multi-second) latency
|
|
50
|
-
let intersectionObserver = window == top ? false : undefined;
|
|
51
|
-
const intersectionObserverElements = [];
|
|
52
|
-
// .map/.findIndex are safe here as they are only used for intersectionObserver
|
|
53
|
-
function atf(adUnit, cb) {
|
|
54
|
-
analyticsCommand(COMMAND.TOSELECTOR, { bid: { adUnitCode: adUnit.code } }, function(selector) {
|
|
55
|
-
const element = document.querySelector(selector);
|
|
56
|
-
if (!element) return cb(null);
|
|
57
|
-
|
|
58
|
-
if (window.getComputedStyle(element)['display'] == 'none') return cb(NaN);
|
|
59
|
-
|
|
60
|
-
try {
|
|
61
|
-
// short circuit for cross-origin
|
|
62
|
-
if (intersectionObserver) throw false;
|
|
63
|
-
|
|
64
|
-
// Google's advice is to collapse slots on no fill but
|
|
65
|
-
// we have to cater to clients that grow slots on fill
|
|
66
|
-
const rect = (function(rect) {
|
|
67
|
-
const sizes = getAdUnitSizes(adUnit);
|
|
68
|
-
|
|
69
|
-
if (sizes.length == 0) return false;
|
|
70
|
-
// interstitial (0x0, 1x1)
|
|
71
|
-
if (sizes.length == 1 && (sizes[0][0] * sizes[0][1]) <= 1) return true;
|
|
72
|
-
// try to catch premium slots (coord=0,0) as they will likely bounce into view
|
|
73
|
-
if (rect.top <= -window.pageYOffset && rect.left <= -window.pageXOffset && rect.top == rect.bottom) return true;
|
|
74
|
-
|
|
75
|
-
// pick the smallest creative size as many publishers will just leave the element unbounded in the vertical
|
|
76
|
-
let width = Infinity;
|
|
77
|
-
let height = Infinity;
|
|
78
|
-
for (let i = 0; i < sizes.length; i++) {
|
|
79
|
-
const area = sizes[i][0] * sizes[i][1];
|
|
80
|
-
if (area < CREATIVE_AREA_MIN) continue;
|
|
81
|
-
if (area < (width * height)) {
|
|
82
|
-
width = sizes[i][0];
|
|
83
|
-
height = sizes[i][1];
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// we also scale the smallest size to the size of the slot as publishers resize units depending on viewport
|
|
87
|
-
const scale = Math.min(1, (rect.right - rect.left) / width);
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
left: rect.left,
|
|
91
|
-
right: rect.left + Math.max(CREATIVE_WIDTH_MIN, scale * width),
|
|
92
|
-
top: rect.top,
|
|
93
|
-
bottom: rect.top + Math.max(CREATIVE_HEIGHT_MIN, scale * height)
|
|
94
|
-
};
|
|
95
|
-
})(element.getBoundingClientRect());
|
|
96
|
-
|
|
97
|
-
if (rect === false) return cb(NaN);
|
|
98
|
-
if (rect === true) return cb(1);
|
|
99
|
-
|
|
100
|
-
const W = rect.right - rect.left;
|
|
101
|
-
const H = rect.bottom - rect.top;
|
|
102
|
-
|
|
103
|
-
if (W * H < CREATIVE_AREA_MIN) return cb(NaN);
|
|
104
|
-
|
|
105
|
-
let el;
|
|
106
|
-
let win = window;
|
|
107
|
-
while (1) {
|
|
108
|
-
// https://stackoverflow.com/a/8876069
|
|
109
|
-
const vw = Math.max(win.document.documentElement.clientWidth || 0, win.innerWidth || 0);
|
|
110
|
-
const vh = Math.max(win.document.documentElement.clientHeight || 0, win.innerHeight || 0);
|
|
111
|
-
|
|
112
|
-
// cut to viewport
|
|
113
|
-
rect.left = Math.min(Math.max(rect.left, 0), vw);
|
|
114
|
-
rect.right = Math.min(Math.max(rect.right, 0), vw);
|
|
115
|
-
rect.top = Math.min(Math.max(rect.top, 0), vh);
|
|
116
|
-
rect.bottom = Math.min(Math.max(rect.bottom, 0), vh);
|
|
117
|
-
|
|
118
|
-
if (win == top) return cb(((rect.right - rect.left) * (rect.bottom - rect.top)) / (W * H));
|
|
119
|
-
el = win.frameElement;
|
|
120
|
-
if (!el) throw false; // cross-origin
|
|
121
|
-
win = win.parent;
|
|
122
|
-
|
|
123
|
-
// transpose to frame element
|
|
124
|
-
const frameElementRect = el.getBoundingClientRect();
|
|
125
|
-
rect.left += frameElementRect.left;
|
|
126
|
-
rect.right = Math.min(rect.right + frameElementRect.left, frameElementRect.right);
|
|
127
|
-
rect.top += frameElementRect.top;
|
|
128
|
-
rect.bottom = Math.min(rect.bottom + frameElementRect.top, frameElementRect.bottom);
|
|
129
|
-
}
|
|
130
|
-
} catch (_) {
|
|
131
|
-
if (intersectionObserver === undefined) {
|
|
132
|
-
try {
|
|
133
|
-
intersectionObserver = new IntersectionObserver(function(entries) {
|
|
134
|
-
entries.forEach(entry => {
|
|
135
|
-
const ratio = entry.intersectionRect.width * entry.intersectionRect.height < CREATIVE_AREA_MIN ? NaN : entry.intersectionRatio;
|
|
136
|
-
const idx = intersectionObserverElements.findIndex(x => x.element == entry.target);
|
|
137
|
-
intersectionObserverElements[idx].cb.forEach(cb => cb(ratio));
|
|
138
|
-
intersectionObserverElements.splice(idx, 1);
|
|
139
|
-
intersectionObserver.unobserve(entry.target);
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
} catch (_) {
|
|
143
|
-
intersectionObserver = false;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
if (!intersectionObserver) return cb(null);
|
|
147
|
-
const idx = intersectionObserverElements.findIndex(x => x.element == element);
|
|
148
|
-
if (idx == -1) {
|
|
149
|
-
intersectionObserverElements.push({ element, cb: [ cb ] });
|
|
150
|
-
intersectionObserver.observe(element);
|
|
151
|
-
} else {
|
|
152
|
-
intersectionObserverElements[idx].cb.push(cb);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
}
|
|
47
|
+
const ADSERVER_TARGETING_PREFIX = 'adl';
|
|
157
48
|
|
|
158
49
|
function init(config, userConsent) {
|
|
159
50
|
logInfo(MODULE, 'init', config, userConsent);
|
|
@@ -167,10 +58,6 @@ function init(config, userConsent) {
|
|
|
167
58
|
logError(MODULE, 'invalid params');
|
|
168
59
|
return false;
|
|
169
60
|
}
|
|
170
|
-
if (!(config.params.api_origin === undefined || isStr(config.params.api_origin))) {
|
|
171
|
-
logError(MODULE, 'invalid api_origin params value');
|
|
172
|
-
return false;
|
|
173
|
-
}
|
|
174
61
|
if (!(config.params.imps === undefined || (isInteger(config.params.imps) && config.params.imps > 0))) {
|
|
175
62
|
logError(MODULE, 'invalid imps params value');
|
|
176
63
|
return false;
|
|
@@ -213,193 +100,110 @@ function init(config, userConsent) {
|
|
|
213
100
|
}
|
|
214
101
|
|
|
215
102
|
function getBidRequestData(reqBidsConfigObj, callback, config, userConsent) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
103
|
+
const adUnits0 = reqBidsConfigObj.adUnits || getGlobal().adUnits;
|
|
104
|
+
// adUnits must be ordered according to adUnitCodes for stable 's' param usage and handling the response below
|
|
105
|
+
const adUnits = reqBidsConfigObj.adUnitCodes.map(code => adUnits0.find(unit => unit.code == code));
|
|
106
|
+
|
|
107
|
+
// buildUrl creates PHP style multi-parameters and includes undefined... (╯°□°)╯ ┻━┻
|
|
108
|
+
const url = buildUrl(mergeDeep(parseUrl(`${API_ORIGIN}/q`), { search: {
|
|
109
|
+
'v': `pbjs-${getGlobal().version}`,
|
|
110
|
+
'c': config.params.clientid,
|
|
111
|
+
'p': config.params.platformid,
|
|
112
|
+
't': config.params.tagid,
|
|
113
|
+
'imp': config.params.imps,
|
|
114
|
+
'fc_ip': config.params.freqcap_ip,
|
|
115
|
+
'fc_ipua': config.params.freqcap_ipua,
|
|
116
|
+
'pn': (getRefererInfo().page || '').substr(0, 300).split(/[?#]/)[0],
|
|
117
|
+
's': _map(adUnits, function(unit) {
|
|
118
|
+
// gptPreAuction runs *after* RTD so pbadslot may not be populated... (╯°□°)╯ ┻━┻
|
|
119
|
+
const gpid = deepAccess(unit, 'ortb2Imp.ext.gpid') ||
|
|
120
|
+
deepAccess(unit, 'ortb2Imp.ext.data.pbadslot') ||
|
|
121
|
+
getGptSlotInfoForAdUnitCode(unit.code).gptSlot ||
|
|
122
|
+
unit.code;
|
|
123
|
+
const ref = [ gpid ];
|
|
124
|
+
if (!config.params.slotinpath) ref.push(unit.code);
|
|
125
|
+
return ref.join('\t');
|
|
126
|
+
})
|
|
127
|
+
} })).replace(/\[\]|[^?&]+=undefined/g, '').replace(/([?&])&+/g, '$1');
|
|
128
|
+
|
|
129
|
+
ajax(url,
|
|
130
|
+
function(responseText, q) {
|
|
131
|
+
function val(v, k) {
|
|
132
|
+
if (!(SEGMENT_HISTORIC[k] && v >= 0)) return v;
|
|
133
|
+
return config.params.thresholds.filter(t => t <= v);
|
|
134
|
+
}
|
|
242
135
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
136
|
+
const response = safeJSONParse(responseText);
|
|
137
|
+
if (!response) {
|
|
138
|
+
logError(MODULE, 'unexpected response');
|
|
139
|
+
return callback();
|
|
140
|
+
}
|
|
246
141
|
|
|
247
|
-
|
|
248
|
-
_each(response
|
|
142
|
+
const { site: ortb2site, user: ortb2user } = reqBidsConfigObj.ortb2Fragments.global;
|
|
143
|
+
_each(response, function(v0, k0) {
|
|
144
|
+
if (k0 == '_') return;
|
|
249
145
|
const k = SEGMENT_HISTORIC[k0] || k0;
|
|
250
146
|
const v = val(v0, k0);
|
|
251
|
-
deepSetValue(
|
|
147
|
+
deepSetValue(k == k0 ? ortb2user : ortb2site, `ext.data.${MODULE_NAME}_rtd.${k}`, v);
|
|
252
148
|
});
|
|
253
|
-
});
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
// mergeDeep does not handle merging deep arrays... (╯°□°)╯ ┻━┻
|
|
257
|
-
function mergeDeep(target, ...sources) {
|
|
258
|
-
function emptyValue(v) {
|
|
259
|
-
if (isPlainObject(v)) {
|
|
260
|
-
return {};
|
|
261
|
-
} else if (isArray(v)) {
|
|
262
|
-
return [];
|
|
263
|
-
} else {
|
|
264
|
-
return undefined;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
149
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
target[key] = target[key] !== undefined ? mergeDeep(target[key], source[key]) : source[key];
|
|
275
|
-
});
|
|
276
|
-
} else if (isArray(target) && isArray(source)) {
|
|
277
|
-
source.forEach((v, i) => {
|
|
278
|
-
if (!(i in target)) target[i] = emptyValue(v);
|
|
279
|
-
target[i] = target[i] !== undefined ? mergeDeep(target[i], v) : v;
|
|
150
|
+
_each(response._, function(segments, i) {
|
|
151
|
+
_each(segments, function(v0, k0) {
|
|
152
|
+
const k = SEGMENT_HISTORIC[k0] || k0;
|
|
153
|
+
const v = val(v0, k0);
|
|
154
|
+
deepSetValue(adUnits[i], `ortb2Imp.ext.data.${MODULE_NAME}_rtd.${k}`, v);
|
|
155
|
+
});
|
|
280
156
|
});
|
|
281
|
-
} else {
|
|
282
|
-
target = source;
|
|
283
|
-
}
|
|
284
157
|
|
|
285
|
-
|
|
286
|
-
}
|
|
158
|
+
deepSetValue(ortb2site, `ext.data.${MODULE_NAME}_rtd.ok`, true);
|
|
287
159
|
|
|
288
|
-
let semaphore = 1;
|
|
289
|
-
function semaphoreInc(inc) {
|
|
290
|
-
if (semaphore == 0) return;
|
|
291
|
-
semaphore += inc;
|
|
292
|
-
if (semaphore == 0) {
|
|
293
|
-
setSegments()
|
|
294
160
|
callback();
|
|
295
161
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const refererInfo = getRefererInfo();
|
|
299
|
-
const args = [
|
|
300
|
-
[ 'v', `pbjs-${getGlobal().version}` ],
|
|
301
|
-
[ 'c', config.params.clientid ],
|
|
302
|
-
[ 'p', config.params.platformid ],
|
|
303
|
-
[ 't', config.params.tagid ],
|
|
304
|
-
[ 'imp', config.params.imps ],
|
|
305
|
-
[ 'fc_ip', config.params.freqcap_ip ],
|
|
306
|
-
[ 'fc_ipua', config.params.freqcap_ipua ],
|
|
307
|
-
[ 'pn', (refererInfo.page || '').substr(0, 300).split(/[?#]/)[0] ]
|
|
308
|
-
];
|
|
309
|
-
|
|
310
|
-
if (!adUnits.length) {
|
|
311
|
-
logWarn(MODULE, 'no suitable adUnits (missing pbadslot?)');
|
|
312
|
-
}
|
|
313
|
-
const atfQueue = [];
|
|
314
|
-
adUnits.map((adUnit, i) => {
|
|
315
|
-
const ref = [ adUnit.gpid ];
|
|
316
|
-
if (!config.params.slotinpath) ref.push(adUnit.unit.code);
|
|
317
|
-
args.push(['s', ref.join('\t')]);
|
|
318
|
-
|
|
319
|
-
semaphoreInc(1);
|
|
320
|
-
atfQueue.push(function() {
|
|
321
|
-
atf(adUnit.unit, function(x) {
|
|
322
|
-
let viewable = document.visibilityState === undefined || document.visibilityState == 'visible';
|
|
323
|
-
try { viewable = viewable && top.document.hasFocus() } catch (_) {}
|
|
324
|
-
logInfo(MODULE, `atf code=${adUnit.unit.code} has area=${x}, viewable=${viewable}`);
|
|
325
|
-
const atfList = []; atfList[i] = { atf: parseInt(x * 100) };
|
|
326
|
-
response = mergeDeep(response, { _: atfList });
|
|
327
|
-
semaphoreInc(-1);
|
|
328
|
-
});
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
function atfCb() {
|
|
332
|
-
atfQueue.forEach(x => x());
|
|
333
|
-
}
|
|
334
|
-
if (document.readyState == 'loading') {
|
|
335
|
-
document.addEventListener('DOMContentLoaded', atfCb, false);
|
|
336
|
-
} else {
|
|
337
|
-
atfCb();
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
analyticsCommand(COMMAND.URL, {
|
|
341
|
-
url: (config.params.api_origin || API_ORIGIN) + '/q?',
|
|
342
|
-
args: args
|
|
343
|
-
}, function(url) {
|
|
344
|
-
ajax(url, {
|
|
345
|
-
success: function(responseText, q) {
|
|
346
|
-
try {
|
|
347
|
-
if (q.getResponseHeader('content-type') == 'application/json') {
|
|
348
|
-
response = mergeDeep(response, JSON.parse(responseText));
|
|
349
|
-
} else {
|
|
350
|
-
throw false;
|
|
351
|
-
}
|
|
352
|
-
} catch (_) {
|
|
353
|
-
logError(MODULE, 'unexpected response');
|
|
354
|
-
}
|
|
355
|
-
semaphoreInc(-1);
|
|
356
|
-
},
|
|
357
|
-
error: function(statusText, q) {
|
|
358
|
-
logError(MODULE, 'request failed');
|
|
359
|
-
semaphoreInc(-1);
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
});
|
|
162
|
+
);
|
|
363
163
|
}
|
|
364
164
|
|
|
365
165
|
function getTargetingData(adUnitArray, config, userConsent, auction) {
|
|
366
|
-
function
|
|
166
|
+
function val(v) {
|
|
367
167
|
if (isArray(v) && v.length == 0) return undefined;
|
|
368
168
|
if (isBoolean(v)) v = ~~v;
|
|
369
169
|
if (!v) return undefined; // empty string and zero
|
|
370
170
|
return v;
|
|
371
171
|
}
|
|
372
172
|
|
|
373
|
-
const
|
|
374
|
-
const dataSite = deepAccess(ortb2, `site.ext.data.${MODULE_NAME}_rtd`) || {};
|
|
375
|
-
if (!dataSite.ok) return {};
|
|
173
|
+
const { site: ortb2site, user: ortb2user } = auctionManager.index.getAuction(auction).getFPD().global;
|
|
376
174
|
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
175
|
+
const ortb2base = {};
|
|
176
|
+
_each(deepAccess(mergeDeep(ortb2site, ortb2user), `ext.data.${MODULE_NAME}_rtd`), function(v0, k) {
|
|
177
|
+
const v = val(v0);
|
|
178
|
+
if (v) ortb2base[`${ADSERVER_TARGETING_PREFIX}_${k}`] = v;
|
|
179
|
+
});
|
|
380
180
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
if (v) a[adUnit.code][ADSERVER_TARGETING_PREFIX + k] = v;
|
|
385
|
-
});
|
|
181
|
+
const targeting = {};
|
|
182
|
+
_each(auction.adUnits.filter(unit => adUnitArray.includes(unit.code)), function(unit) {
|
|
183
|
+
targeting[unit.code] = deepClone(ortb2base);
|
|
386
184
|
|
|
387
|
-
const
|
|
388
|
-
_each(
|
|
389
|
-
const v =
|
|
390
|
-
if (v)
|
|
185
|
+
const ortb2imp = deepAccess(unit, `ortb2Imp.ext.data.${MODULE_NAME}_rtd`);
|
|
186
|
+
_each(ortb2imp, function(v0, k) {
|
|
187
|
+
const v = val(v0);
|
|
188
|
+
if (v) targeting[unit.code][`${ADSERVER_TARGETING_PREFIX}_${k}`] = v;
|
|
391
189
|
});
|
|
392
190
|
|
|
393
|
-
|
|
394
|
-
|
|
191
|
+
// ATF results shamelessly exfiltrated from intersectionRtdProvider
|
|
192
|
+
const bid = unit.bids.find(bid => !!bid.intersection);
|
|
193
|
+
if (bid) {
|
|
194
|
+
const v = val(config.params.thresholds.filter(t => t <= (bid.intersection.intersectionRatio * 100)));
|
|
195
|
+
if (v) targeting[unit.code][`${ADSERVER_TARGETING_PREFIX}_atf`] = v;
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
return targeting;
|
|
395
200
|
}
|
|
396
201
|
|
|
397
202
|
export const subModuleObj = {
|
|
398
203
|
name: MODULE_NAME,
|
|
399
204
|
init,
|
|
400
205
|
getBidRequestData,
|
|
401
|
-
getTargetingData
|
|
402
|
-
atf // used by adlooxRtdProvider_spec.js
|
|
206
|
+
getTargetingData
|
|
403
207
|
};
|
|
404
208
|
|
|
405
209
|
submodule('realTimeData', subModuleObj);
|
|
@@ -19,12 +19,7 @@ This provider fetches segments and populates the [First Party Data](https://docs
|
|
|
19
19
|
* AdUnit segments are placed into `AdUnit.ortb2Imp.ext.data.adloox_rtd`:
|
|
20
20
|
* **`{dis,vid,aud}`:** an list of integers describing the likelihood the AdUnit will be visible
|
|
21
21
|
* **`atf`:** an list of integers describing the percentage of pixels visible at auction
|
|
22
|
-
* measured
|
|
23
|
-
* usable when the publisher uses the strategy of collapsing ad slots on no-fill
|
|
24
|
-
* using the reverse strategy, growing ad slots on fill, invalidates the measurement the position of all content (including the slots) changes post-auction
|
|
25
|
-
* works best when your page loads your ad slots have their actual size rendered (ie. not zero height)
|
|
26
|
-
* uses the smallest ad unit (above a threshold area of 20x20) supplied by the [publisher to Prebid.js](https://docs.prebid.org/dev-docs/examples/basic-example.html) and measures viewability as if that size to be used
|
|
27
|
-
* when used in cross-origin (unfriendly) IFRAME environments the ad slot is directly measured as is (ignoring publisher provided sizes) due to limitations in using [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver)
|
|
22
|
+
* measured at pre-auction time using the [Intersection Module](https://docs.prebid.org/dev-docs/modules/intersectionRtdProvider.html); if not enabled then this measurement is not available
|
|
28
23
|
|
|
29
24
|
**N.B.** this provider does not offer or utilise any user orientated data
|
|
30
25
|
|
|
@@ -57,8 +52,13 @@ To use this, you *must* also integrate the [Adloox Analytics Adapter](./adlooxAn
|
|
|
57
52
|
realTimeData: {
|
|
58
53
|
auctionDelay: 100, // see below for guidance
|
|
59
54
|
dataProviders: [
|
|
55
|
+
{
|
|
56
|
+
name: 'intersection',
|
|
57
|
+
waitForIt: true
|
|
58
|
+
},
|
|
60
59
|
{
|
|
61
60
|
name: 'adloox',
|
|
61
|
+
waitForIt: true,
|
|
62
62
|
params: { // optional, defaults shown
|
|
63
63
|
thresholds: [ 50, 60, 70, 80, 90 ],
|
|
64
64
|
slotinpath: false
|
|
@@ -220,6 +220,8 @@ function setPrebidImpressionObject(bidRequests, payload) {
|
|
|
220
220
|
deepSetValue(impressionObject, 'id', bidRequest.bidId);
|
|
221
221
|
// Transaction id
|
|
222
222
|
deepSetValue(impressionObject, 'tid', deepAccess(bidRequest, 'transactionId'));
|
|
223
|
+
// Placement id
|
|
224
|
+
deepSetValue(impressionObject, 'tagid', deepAccess(bidRequest, 'params.placementId', null));
|
|
223
225
|
// Publisher id
|
|
224
226
|
deepSetValue(payload, 'site.publisher.id', deepAccess(bidRequest, 'params.publisherId'));
|
|
225
227
|
// Site id
|
|
@@ -265,6 +267,8 @@ function setPrebidRequestEnvironment(payload) {
|
|
|
265
267
|
deepSetValue(payload, 'environment.inp.jp', window.JSON.parse.name === 'parse' && typeof window.JSON.parse.prototype === 'undefined');
|
|
266
268
|
deepSetValue(payload, 'environment.inp.ofe', window.Object.fromEntries.name === 'fromEntries' && typeof window.Object.fromEntries.prototype === 'undefined');
|
|
267
269
|
deepSetValue(payload, 'environment.inp.oa', window.Object.assign.name === 'assign' && typeof window.Object.assign.prototype === 'undefined');
|
|
270
|
+
deepSetValue(payload, 'environment.wpar.innerWidth', window.innerWidth);
|
|
271
|
+
deepSetValue(payload, 'environment.wpar.innerHeight', window.innerHeight);
|
|
268
272
|
}
|
|
269
273
|
|
|
270
274
|
function setPrebidImpressionObjectFloor(bidRequest, impressionObject) {
|
|
@@ -18,6 +18,7 @@ This module is GDPR and CCPA compliant, and no 3rd party userIds are allowed.
|
|
|
18
18
|
|---------------|----------|---------------------|---------------|----------|
|
|
19
19
|
| `siteId` | required | Unique site ID | `'ABCDEF'` | `String` |
|
|
20
20
|
| `publisherId` | required | Unique publisher ID | `'ABCDEF'` | `String` |
|
|
21
|
+
| `placementId` | optional | Unique publisher tag ID | `'ABCDEF'` | `String` |
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
### Banner Bid Params
|
|
@@ -20,18 +20,20 @@ export const spec = {
|
|
|
20
20
|
let bidIds = [];
|
|
21
21
|
let eids;
|
|
22
22
|
validBidRequests.forEach(bidRequest => {
|
|
23
|
-
let
|
|
23
|
+
let formatType = getFormatType(bidRequest)
|
|
24
|
+
let alkimiSizes = prepareAlkimiSizes(bidRequest.sizes)
|
|
24
25
|
|
|
25
26
|
if (bidRequest.userIdAsEids) {
|
|
26
27
|
eids = eids || bidRequest.userIdAsEids
|
|
27
28
|
}
|
|
29
|
+
|
|
28
30
|
bids.push({
|
|
29
31
|
token: bidRequest.params.token,
|
|
30
32
|
pos: bidRequest.params.pos,
|
|
31
|
-
bidFloor: bidRequest
|
|
32
|
-
width:
|
|
33
|
-
height:
|
|
34
|
-
impMediaType:
|
|
33
|
+
bidFloor: getBidFloor(bidRequest, formatType),
|
|
34
|
+
width: alkimiSizes[0].width,
|
|
35
|
+
height: alkimiSizes[0].height,
|
|
36
|
+
impMediaType: formatType,
|
|
35
37
|
adUnitCode: bidRequest.adUnitCode
|
|
36
38
|
})
|
|
37
39
|
bidIds.push(bidRequest.bidId)
|
|
@@ -128,10 +130,25 @@ export const spec = {
|
|
|
128
130
|
}
|
|
129
131
|
}
|
|
130
132
|
|
|
131
|
-
function
|
|
133
|
+
function prepareAlkimiSizes(sizes) {
|
|
132
134
|
return sizes && sizes.map(size => ({ width: size[0], height: size[1] }));
|
|
133
135
|
}
|
|
134
136
|
|
|
137
|
+
function prepareBidFloorSize(sizes) {
|
|
138
|
+
return sizes && sizes.length === 1 ? sizes[0] : '*';
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function getBidFloor(bidRequest, formatType) {
|
|
142
|
+
if (typeof bidRequest.getFloor === 'function') {
|
|
143
|
+
const bidFloorSize = prepareBidFloorSize(bidRequest.sizes)
|
|
144
|
+
const floor = bidRequest.getFloor({ currency: 'USD', mediaType: formatType.toLowerCase(), size: bidFloorSize });
|
|
145
|
+
if (floor && !isNaN(floor.floor) && (floor.currency === 'USD')) {
|
|
146
|
+
return floor.floor;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return bidRequest.params.bidFloor;
|
|
150
|
+
}
|
|
151
|
+
|
|
135
152
|
const getFormatType = bidRequest => {
|
|
136
153
|
if (deepAccess(bidRequest, 'mediaTypes.banner')) return 'Banner'
|
|
137
154
|
if (deepAccess(bidRequest, 'mediaTypes.video')) return 'Video'
|
package/modules/aolBidAdapter.js
CHANGED
|
@@ -159,6 +159,13 @@ export const spec = {
|
|
|
159
159
|
if (bidderRequest) {
|
|
160
160
|
consentData.gdpr = bidderRequest.gdprConsent;
|
|
161
161
|
consentData.uspConsent = bidderRequest.uspConsent;
|
|
162
|
+
consentData.gppConsent = bidderRequest.gppConsent;
|
|
163
|
+
if (!consentData.gppConsent && bidderRequest.ortb2?.regs?.gpp) {
|
|
164
|
+
consentData.gppConsent = {
|
|
165
|
+
gppString: bidderRequest.ortb2.regs.gpp,
|
|
166
|
+
applicableSections: bidderRequest.ortb2.regs.gpp_sid
|
|
167
|
+
}
|
|
168
|
+
}
|
|
162
169
|
}
|
|
163
170
|
|
|
164
171
|
return bids.map(bid => {
|
|
@@ -373,6 +380,11 @@ export const spec = {
|
|
|
373
380
|
params.us_privacy = consentData.uspConsent;
|
|
374
381
|
}
|
|
375
382
|
|
|
383
|
+
if (consentData.gppConsent && consentData.gppConsent.gppString) {
|
|
384
|
+
params.gpp = consentData.gppConsent.gppString;
|
|
385
|
+
params.gpp_sid = consentData.gppConsent.applicableSections;
|
|
386
|
+
}
|
|
387
|
+
|
|
376
388
|
return params;
|
|
377
389
|
},
|
|
378
390
|
parsePixelItems(pixels) {
|
|
@@ -625,9 +625,8 @@ function newBid(serverBid, rtbBid, bidderRequest) {
|
|
|
625
625
|
}
|
|
626
626
|
};
|
|
627
627
|
|
|
628
|
-
// WE DON'T FULLY SUPPORT THIS ATM - future spot for adomain code; creating a stub for 5.0 compliance
|
|
629
628
|
if (rtbBid.adomain) {
|
|
630
|
-
bid.meta = Object.assign({}, bid.meta, { advertiserDomains: [] });
|
|
629
|
+
bid.meta = Object.assign({}, bid.meta, { advertiserDomains: [rtbBid.adomain] });
|
|
631
630
|
}
|
|
632
631
|
|
|
633
632
|
if (rtbBid.advertiser_id) {
|
|
@@ -731,6 +730,7 @@ function newBid(serverBid, rtbBid, bidderRequest) {
|
|
|
731
730
|
displayUrl: nativeAd.displayurl,
|
|
732
731
|
clickTrackers: nativeAd.link.click_trackers,
|
|
733
732
|
impressionTrackers: nativeAd.impression_trackers,
|
|
733
|
+
video: nativeAd.video,
|
|
734
734
|
javascriptTrackers: jsTrackers
|
|
735
735
|
};
|
|
736
736
|
if (nativeAd.main_img) {
|