prebid.js 7.4.0 → 7.7.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.
Files changed (239) hide show
  1. package/.circleci/config.yml +11 -6
  2. package/dist/1plusXRtdProvider.js +1 -0
  3. package/dist/33acrossBidAdapter.js +1 -1
  4. package/dist/adagioBidAdapter.js +1 -1
  5. package/dist/adbookpspBidAdapter.js +1 -1
  6. package/dist/adgenerationBidAdapter.js +1 -1
  7. package/dist/adnuntiusBidAdapter.js +1 -1
  8. package/dist/adoceanBidAdapter.js +1 -1
  9. package/dist/adotBidAdapter.js +1 -1
  10. package/dist/adrelevantisBidAdapter.js +1 -1
  11. package/dist/adrinoBidAdapter.js +1 -1
  12. package/dist/adtelligentBidAdapter.js +1 -1
  13. package/dist/adxcgBidAdapter.js +1 -1
  14. package/dist/ajaBidAdapter.js +1 -1
  15. package/dist/amxBidAdapter.js +1 -1
  16. package/dist/amxIdSystem.js +1 -1
  17. package/dist/appierAnalyticsAdapter.js +1 -1
  18. package/dist/appnexusBidAdapter.js +1 -1
  19. package/dist/asoBidAdapter.js +1 -1
  20. package/dist/atsAnalyticsAdapter.js +1 -1
  21. package/dist/axonixBidAdapter.js +1 -1
  22. package/dist/bidglassBidAdapter.js +1 -1
  23. package/dist/big-richmediaBidAdapter.js +1 -1
  24. package/dist/bliinkBidAdapter.js +1 -1
  25. package/dist/bridgewellBidAdapter.js +1 -1
  26. package/dist/brightMountainMediaBidAdapter.js +1 -1
  27. package/dist/byDataAnalyticsAdapter.js +1 -1
  28. package/dist/concertBidAdapter.js +1 -1
  29. package/dist/connectadBidAdapter.js +1 -1
  30. package/dist/consumableBidAdapter.js +1 -1
  31. package/dist/conversantBidAdapter.js +1 -1
  32. package/dist/craftBidAdapter.js +1 -1
  33. package/dist/criteoBidAdapter.js +1 -1
  34. package/dist/currency.js +1 -1
  35. package/dist/dspxBidAdapter.js +1 -1
  36. package/dist/eplanningBidAdapter.js +1 -1
  37. package/dist/finativeBidAdapter.js +1 -1
  38. package/dist/gdprEnforcement.js +1 -1
  39. package/dist/glimpseBidAdapter.js +1 -1
  40. package/dist/gmosspBidAdapter.js +1 -1
  41. package/dist/goldbachBidAdapter.js +1 -1
  42. package/dist/gridBidAdapter.js +1 -1
  43. package/dist/gridNMBidAdapter.js +1 -1
  44. package/dist/gumgumBidAdapter.js +1 -1
  45. package/dist/h12mediaBidAdapter.js +1 -1
  46. package/dist/hadronIdSystem.js +1 -1
  47. package/dist/hadronRtdProvider.js +1 -1
  48. package/dist/id5IdSystem.js +1 -1
  49. package/dist/imRtdProvider.js +1 -1
  50. package/dist/impactifyBidAdapter.js +1 -1
  51. package/dist/improvedigitalBidAdapter.js +1 -1
  52. package/dist/inmarBidAdapter.js +1 -1
  53. package/dist/insticatorBidAdapter.js +1 -1
  54. package/dist/ixBidAdapter.js +1 -1
  55. package/dist/jixieBidAdapter.js +1 -1
  56. package/dist/justpremiumBidAdapter.js +1 -1
  57. package/dist/kargoAnalyticsAdapter.js +1 -1
  58. package/dist/konduitAnalyticsAdapter.js +1 -1
  59. package/dist/kueezBidAdapter.js +1 -1
  60. package/dist/lassoBidAdapter.js +1 -1
  61. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  62. package/dist/logicadBidAdapter.js +1 -1
  63. package/dist/loglyliftBidAdapter.js +1 -1
  64. package/dist/malltvAnalyticsAdapter.js +1 -1
  65. package/dist/marsmediaBidAdapter.js +1 -1
  66. package/dist/mediafuseBidAdapter.js +1 -1
  67. package/dist/mediasquareBidAdapter.js +1 -1
  68. package/dist/mgidBidAdapter.js +1 -1
  69. package/dist/minutemediaBidAdapter.js +1 -1
  70. package/dist/naveggIdSystem.js +1 -1
  71. package/dist/newspassidBidAdapter.js +1 -0
  72. package/dist/nextMillenniumBidAdapter.js +1 -1
  73. package/dist/not-for-prod/prebid.js +131 -128
  74. package/dist/oguryBidAdapter.js +1 -1
  75. package/dist/onetagBidAdapter.js +1 -1
  76. package/dist/ooloAnalyticsAdapter.js +1 -1
  77. package/dist/outbrainBidAdapter.js +1 -1
  78. package/dist/parrableIdSystem.js +1 -1
  79. package/dist/pixfutureBidAdapter.js +1 -1
  80. package/dist/prebid-core.js +1 -1
  81. package/dist/prebidServerBidAdapter.js +1 -1
  82. package/dist/priceFloors.js +1 -1
  83. package/dist/pubCommonId.js +1 -1
  84. package/dist/publinkIdSystem.js +1 -1
  85. package/dist/pubmaticBidAdapter.js +1 -1
  86. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  87. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  88. package/dist/pxyzBidAdapter.js +1 -1
  89. package/dist/quantcastBidAdapter.js +1 -1
  90. package/dist/rasBidAdapter.js +1 -0
  91. package/dist/readpeakBidAdapter.js +1 -1
  92. package/dist/relaidoBidAdapter.js +1 -1
  93. package/dist/rhythmoneBidAdapter.js +1 -1
  94. package/dist/riseBidAdapter.js +1 -1
  95. package/dist/rubiconAnalyticsAdapter.js +1 -1
  96. package/dist/rubiconBidAdapter.js +1 -1
  97. package/dist/seedingAllianceBidAdapter.js +1 -1
  98. package/dist/seedtagBidAdapter.js +1 -1
  99. package/dist/sharedIdSystem.js +1 -1
  100. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  101. package/dist/sharethroughBidAdapter.js +1 -1
  102. package/dist/shinezBidAdapter.js +1 -1
  103. package/dist/smaatoBidAdapter.js +1 -1
  104. package/dist/smartadserverBidAdapter.js +1 -1
  105. package/dist/smartxBidAdapter.js +1 -1
  106. package/dist/smilewantedBidAdapter.js +1 -1
  107. package/dist/sonobiBidAdapter.js +1 -1
  108. package/dist/sovrnAnalyticsAdapter.js +1 -1
  109. package/dist/sovrnBidAdapter.js +1 -1
  110. package/dist/sspBCBidAdapter.js +1 -1
  111. package/dist/sublimeBidAdapter.js +1 -1
  112. package/dist/synacormediaBidAdapter.js +1 -1
  113. package/dist/taboolaBidAdapter.js +1 -1
  114. package/dist/targetVideoBidAdapter.js +1 -1
  115. package/dist/teadsBidAdapter.js +1 -1
  116. package/dist/trionBidAdapter.js +1 -1
  117. package/dist/tripleliftBidAdapter.js +1 -1
  118. package/dist/ttdBidAdapter.js +1 -1
  119. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  120. package/dist/underdogmediaBidAdapter.js +1 -1
  121. package/dist/undertoneBidAdapter.js +1 -1
  122. package/dist/userId.js +1 -1
  123. package/dist/vidazooBidAdapter.js +1 -1
  124. package/dist/videobyteBidAdapter.js +1 -1
  125. package/dist/visxBidAdapter.js +1 -1
  126. package/dist/vuukleBidAdapter.js +1 -1
  127. package/dist/widespaceBidAdapter.js +1 -1
  128. package/dist/winrBidAdapter.js +1 -1
  129. package/dist/yahoosspBidAdapter.js +1 -1
  130. package/dist/yieldmoBidAdapter.js +1 -1
  131. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  132. package/integrationExamples/gpt/1plusXRtdProviderExample.html +112 -0
  133. package/karma.conf.maker.js +3 -1
  134. package/modules/.submodules.json +2 -1
  135. package/modules/1plusXRtdProvider.js +251 -0
  136. package/modules/1plusXRtdProvider.md +65 -0
  137. package/modules/adgenerationBidAdapter.js +24 -1
  138. package/modules/adnuntiusBidAdapter.js +26 -8
  139. package/modules/adoceanBidAdapter.js +10 -3
  140. package/modules/adotBidAdapter.js +13 -4
  141. package/modules/adrinoBidAdapter.js +10 -2
  142. package/modules/adrinoBidAdapter.md +6 -0
  143. package/modules/adtelligentBidAdapter.js +2 -1
  144. package/modules/appnexusBidAdapter.js +3 -3
  145. package/modules/atsAnalyticsAdapter.js +4 -5
  146. package/modules/big-richmediaBidAdapter.js +3 -3
  147. package/modules/bliinkBidAdapter.js +120 -193
  148. package/modules/bliinkBidAdapter.md +2 -5
  149. package/modules/byDataAnalyticsAdapter.js +172 -74
  150. package/modules/byDataAnalyticsAdapter.md +5 -6
  151. package/modules/consumableBidAdapter.js +21 -1
  152. package/modules/criteoBidAdapter.js +7 -1
  153. package/modules/currency.js +2 -2
  154. package/modules/cwireBidAdapter.md +1 -1
  155. package/modules/eplanningBidAdapter.js +82 -97
  156. package/modules/gdprEnforcement.js +8 -14
  157. package/modules/gridNMBidAdapter.js +45 -4
  158. package/modules/hadronAnalyticsAdapter.md +5 -5
  159. package/modules/hadronIdSystem.js +18 -5
  160. package/modules/hadronIdSystem.md +15 -11
  161. package/modules/hadronRtdProvider.js +14 -1
  162. package/modules/hadronRtdProvider.md +17 -13
  163. package/modules/imRtdProvider.js +0 -8
  164. package/modules/impactifyBidAdapter.js +6 -2
  165. package/modules/ixBidAdapter.js +133 -23
  166. package/modules/ixBidAdapter.md +2 -5
  167. package/modules/jixieBidAdapter.js +10 -10
  168. package/modules/kargoAnalyticsAdapter.js +88 -6
  169. package/modules/kargoAnalyticsAdapter.md +33 -0
  170. package/modules/minutemediaBidAdapter.js +1 -0
  171. package/modules/naveggIdSystem.js +1 -12
  172. package/modules/newspassidBidAdapter.js +649 -0
  173. package/modules/nextMillenniumBidAdapter.js +17 -1
  174. package/modules/nextMillenniumBidAdapter.md +1 -1
  175. package/modules/oguryBidAdapter.js +2 -0
  176. package/modules/onetagBidAdapter.js +44 -7
  177. package/modules/prebidServerBidAdapter/index.js +7 -0
  178. package/modules/priceFloors.js +1 -1
  179. package/modules/pubCommonId.js +1 -2
  180. package/modules/pubxaiAnalyticsAdapter.js +6 -1
  181. package/modules/rasBidAdapter.js +149 -0
  182. package/modules/rasBidAdapter.md +50 -0
  183. package/modules/rubiconBidAdapter.js +5 -0
  184. package/modules/seedingAllianceBidAdapter.js +3 -0
  185. package/modules/seedtagBidAdapter.js +37 -1
  186. package/modules/sharedIdSystem.js +11 -5
  187. package/modules/sharethroughBidAdapter.js +9 -24
  188. package/modules/taboolaBidAdapter.js +1 -1
  189. package/modules/taboolaBidAdapter.md +3 -3
  190. package/modules/targetVideoBidAdapter.js +18 -0
  191. package/modules/userId/index.js +39 -21
  192. package/package.json +1 -1
  193. package/src/auction.js +6 -5
  194. package/src/consentHandler.js +11 -11
  195. package/src/debugging.js +5 -3
  196. package/src/hook.js +2 -2
  197. package/src/storageManager.js +4 -5
  198. package/src/utils/promise.js +96 -21
  199. package/src/utils.js +3 -2
  200. package/test/helpers/consentData.js +2 -1
  201. package/test/spec/auctionmanager_spec.js +1 -6
  202. package/test/spec/debugging_spec.js +2 -2
  203. package/test/spec/modules/1plusXRtdProvider_spec.js +430 -0
  204. package/test/spec/modules/adgenerationBidAdapter_spec.js +52 -4
  205. package/test/spec/modules/adnuntiusBidAdapter_spec.js +126 -14
  206. package/test/spec/modules/adoceanBidAdapter_spec.js +4 -1
  207. package/test/spec/modules/adotBidAdapter_spec.js +12 -9
  208. package/test/spec/modules/adrinoBidAdapter_spec.js +22 -0
  209. package/test/spec/modules/appnexusBidAdapter_spec.js +165 -156
  210. package/test/spec/modules/bliinkBidAdapter_spec.js +323 -136
  211. package/test/spec/modules/byDataAnalyticsAdapter_spec.js +74 -24
  212. package/test/spec/modules/consumableBidAdapter_spec.js +122 -1
  213. package/test/spec/modules/criteoBidAdapter_spec.js +15 -5
  214. package/test/spec/modules/eplanningBidAdapter_spec.js +58 -18
  215. package/test/spec/modules/gdprEnforcement_spec.js +53 -100
  216. package/test/spec/modules/gridNMBidAdapter_spec.js +32 -0
  217. package/test/spec/modules/hadronIdSystem_spec.js +2 -2
  218. package/test/spec/modules/idxIdSystem_spec.js +1 -1
  219. package/test/spec/modules/imRtdProvider_spec.js +0 -1
  220. package/test/spec/modules/ixBidAdapter_spec.js +212 -5
  221. package/test/spec/modules/jixieBidAdapter_spec.js +8 -8
  222. package/test/spec/modules/kargoAnalyticsAdapter_spec.js +42 -0
  223. package/test/spec/modules/minutemediaBidAdapter_spec.js +3 -0
  224. package/test/spec/modules/newspassidBidAdapter_spec.js +1793 -0
  225. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +20 -0
  226. package/test/spec/modules/onetagBidAdapter_spec.js +53 -4
  227. package/test/spec/modules/parrableIdSystem_spec.js +2 -1
  228. package/test/spec/modules/prebidServerBidAdapter_spec.js +20 -0
  229. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +5 -0
  230. package/test/spec/modules/rasBidAdapter_spec.js +190 -0
  231. package/test/spec/modules/rubiconBidAdapter_spec.js +27 -0
  232. package/test/spec/modules/seedtagBidAdapter_spec.js +29 -0
  233. package/test/spec/modules/sharethroughBidAdapter_spec.js +4 -4
  234. package/test/spec/modules/taboolaBidAdapter_spec.js +1 -1
  235. package/test/spec/modules/targetVideoBidAdapter_spec.js +43 -0
  236. package/test/spec/modules/userId_spec.js +15 -2
  237. package/test/spec/unit/pbjs_api_spec.js +1 -5
  238. package/test/spec/unit/utils/promise_spec.js +283 -38
  239. package/test/helpers/syncPromise.js +0 -71
@@ -1,4 +1,4 @@
1
- import {getWindowSelf, isEmpty, parseSizesInput} from '../src/utils.js';
1
+ import {getWindowSelf, isEmpty, parseSizesInput, isGptPubadsDefined, isSlotMatchingAdUnitCode} from '../src/utils.js';
2
2
  import {getGlobal} from '../src/prebidGlobal.js';
3
3
  import {registerBidder} from '../src/adapters/bidderFactory.js';
4
4
  import {getStorageManager} from '../src/storageManager.js';
@@ -291,13 +291,25 @@ function getCharset() {
291
291
 
292
292
  function waitForElementsPresent(elements) {
293
293
  const observer = new MutationObserver(function (mutationList, observer) {
294
+ let index;
295
+ let adView;
294
296
  if (mutationList && Array.isArray(mutationList)) {
295
297
  mutationList.forEach(mr => {
296
298
  if (mr && mr.addedNodes && Array.isArray(mr.addedNodes)) {
297
299
  mr.addedNodes.forEach(ad => {
298
- let index = elements.indexOf(ad.id);
300
+ index = elements.indexOf(ad.id);
301
+ adView = ad;
302
+ if (index < 0) {
303
+ elements.forEach(code => {
304
+ let div = _getAdSlotHTMLElement(code);
305
+ if (div && div.contains(ad) && div.getBoundingClientRect().width > 0) {
306
+ index = elements.indexOf(div.id);
307
+ adView = div;
308
+ }
309
+ });
310
+ }
299
311
  if (index >= 0) {
300
- registerViewability(ad);
312
+ registerViewability(adView, elements[index]);
301
313
  elements.splice(index, 1);
302
314
  if (!elements.length) {
303
315
  observer.disconnect();
@@ -318,19 +330,41 @@ function waitForElementsPresent(elements) {
318
330
  });
319
331
  }
320
332
 
321
- function registerViewability(div) {
333
+ function registerViewability(div, name) {
322
334
  visibilityHandler({
323
- name: div.id,
335
+ name: name,
324
336
  div: div
325
337
  });
326
338
  }
327
339
 
340
+ function _mapAdUnitPathToElementId(adUnitCode) {
341
+ if (isGptPubadsDefined()) {
342
+ // eslint-disable-next-line no-undef
343
+ const adSlots = googletag.pubads().getSlots();
344
+ const isMatchingAdSlot = isSlotMatchingAdUnitCode(adUnitCode);
345
+
346
+ for (let i = 0; i < adSlots.length; i++) {
347
+ if (isMatchingAdSlot(adSlots[i])) {
348
+ const id = adSlots[i].getSlotElementId();
349
+ return id;
350
+ }
351
+ }
352
+ }
353
+
354
+ return null;
355
+ }
356
+
357
+ function _getAdSlotHTMLElement(adUnitCode) {
358
+ return document.getElementById(adUnitCode) ||
359
+ document.getElementById(_mapAdUnitPathToElementId(adUnitCode));
360
+ }
361
+
328
362
  function registerViewabilityAllBids(bids) {
329
363
  let elementsNotPresent = [];
330
364
  bids.forEach(bid => {
331
- let div = document.getElementById(bid.adUnitCode);
365
+ let div = _getAdSlotHTMLElement(bid.adUnitCode);
332
366
  if (div) {
333
- registerViewability(div);
367
+ registerViewability(div, bid.adUnitCode);
334
368
  } else {
335
369
  elementsNotPresent.push(bid.adUnitCode);
336
370
  }
@@ -345,114 +379,65 @@ function getViewabilityTracker() {
345
379
  let VIEWABILITY_TIME = 1000;
346
380
  let VIEWABILITY_MIN_RATIO = 0.5;
347
381
  let publicApi;
348
- let context;
349
-
350
- function segmentIsOutsideTheVisibleRange(visibleRangeEnd, p1, p2) {
351
- return p1 > visibleRangeEnd || p2 < 0;
352
- }
353
-
354
- function segmentBeginsBeforeTheVisibleRange(p1) {
355
- return p1 < 0;
356
- }
357
-
358
- function segmentEndsAfterTheVisibleRange(visibleRangeEnd, p2) {
359
- return p2 < visibleRangeEnd;
360
- }
361
-
362
- function axialVisibilityRatio(visibleRangeEnd, p1, p2) {
363
- let visibilityRatio = 0;
364
- if (!segmentIsOutsideTheVisibleRange(visibleRangeEnd, p1, p2)) {
365
- if (segmentBeginsBeforeTheVisibleRange(p1)) {
366
- visibilityRatio = p2 / (p2 - p1);
382
+ let observer;
383
+ let visibilityAds = {};
384
+
385
+ function intersectionCallback(entries) {
386
+ entries.forEach(function(entry) {
387
+ var adBox = entry.target;
388
+ if (entry.isIntersecting) {
389
+ if (entry.intersectionRatio >= VIEWABILITY_MIN_RATIO && entry.boundingClientRect && entry.boundingClientRect.height > 0 && entry.boundingClientRect.width > 0) {
390
+ visibilityAds[adBox.id] = true;
391
+ }
367
392
  } else {
368
- visibilityRatio = segmentEndsAfterTheVisibleRange(visibleRangeEnd, p2) ? 1 : (visibleRangeEnd - p1) / (p2 - p1);
393
+ visibilityAds[adBox.id] = false;
369
394
  }
370
- }
371
- return visibilityRatio;
372
- }
373
-
374
- function isNotHiddenByNonFriendlyIframe() {
375
- try { return (window === window.top) || window.frameElement; } catch (e) {}
376
- }
377
-
378
- function defineContext(e) {
379
- try {
380
- context = e && window.document.body.contains(e) ? window : (window.top.document.body.contains(e) ? top : undefined);
381
- } catch (err) {}
382
- return context;
383
- }
384
-
385
- function getContext(e) {
386
- return context;
387
- }
388
-
389
- function verticalVisibilityRatio(position) {
390
- return axialVisibilityRatio(getContext().innerHeight, position.top, position.bottom);
391
- }
392
-
393
- function horizontalVisibilityRatio(position) {
394
- return axialVisibilityRatio(getContext().innerWidth, position.left, position.right);
395
- }
396
-
397
- function itIsNotHiddenByBannerAreaPosition(e) {
398
- let position = e.getBoundingClientRect();
399
- return (verticalVisibilityRatio(position) * horizontalVisibilityRatio(position)) > VIEWABILITY_MIN_RATIO;
400
- }
401
-
402
- function itIsNotHiddenByDisplayStyleCascade(e) {
403
- return e.offsetHeight > 0 && e.offsetWidth > 0;
404
- }
405
-
406
- function itIsNotHiddenByOpacityStyleCascade(e) {
407
- let s = e.style;
408
- let p = e.parentNode;
409
- return !(s && parseFloat(s.opacity) === 0) && (!p || itIsNotHiddenByOpacityStyleCascade(p));
410
- }
411
-
412
- function itIsNotHiddenByVisibilityStyleCascade(e) {
413
- return getContext().getComputedStyle(e).visibility !== 'hidden';
414
- }
415
-
416
- function itIsNotHiddenByTabFocus() {
417
- try { return getContext().top.document.hasFocus(); } catch (e) {}
418
- }
419
-
420
- function isDefined(e) {
421
- return (e !== null) && (typeof e !== 'undefined');
395
+ });
422
396
  }
423
397
 
424
- function itIsNotHiddenByOrphanBranch() {
425
- return isDefined(getContext());
398
+ function observedElementIsVisible(element) {
399
+ return visibilityAds[element.id] && document.visibilityState && document.visibilityState === 'visible';
426
400
  }
427
401
 
428
- function isContextInAnIframe() {
429
- return isDefined(getContext().frameElement);
402
+ function defineObserver() {
403
+ if (!observer) {
404
+ var observerConfig = {
405
+ root: null,
406
+ rootMargin: '0px',
407
+ threshold: [VIEWABILITY_MIN_RATIO]
408
+ };
409
+ observer = new IntersectionObserver(intersectionCallback.bind(this), observerConfig);
410
+ }
430
411
  }
431
-
432
412
  function processIntervalVisibilityStatus(elapsedVisibleIntervals, element, callback) {
433
- let visibleIntervals = isVisible(element) ? (elapsedVisibleIntervals + 1) : 0;
413
+ let visibleIntervals = observedElementIsVisible(element) ? (elapsedVisibleIntervals + 1) : 0;
434
414
  if (visibleIntervals === TIME_PARTITIONS) {
415
+ stopObserveViewability(element)
435
416
  callback();
436
417
  } else {
437
418
  setTimeout(processIntervalVisibilityStatus.bind(this, visibleIntervals, element, callback), VIEWABILITY_TIME / TIME_PARTITIONS);
438
419
  }
439
420
  }
440
421
 
441
- function isVisible(element) {
442
- defineContext(element);
443
- return isNotHiddenByNonFriendlyIframe() &&
444
- itIsNotHiddenByOrphanBranch() &&
445
- itIsNotHiddenByTabFocus() &&
446
- itIsNotHiddenByDisplayStyleCascade(element) &&
447
- itIsNotHiddenByVisibilityStyleCascade(element) &&
448
- itIsNotHiddenByOpacityStyleCascade(element) &&
449
- itIsNotHiddenByBannerAreaPosition(element) &&
450
- (!isContextInAnIframe() || isVisible(getContext().frameElement));
422
+ function stopObserveViewability(element) {
423
+ delete visibilityAds[element.id];
424
+ observer.unobserve(element);
425
+ }
426
+
427
+ function observeAds(element) {
428
+ observer.observe(element);
429
+ }
430
+
431
+ function initAndVerifyVisibility(element, callback) {
432
+ if (element) {
433
+ defineObserver();
434
+ observeAds(element);
435
+ processIntervalVisibilityStatus(0, element, callback);
436
+ }
451
437
  }
452
438
 
453
439
  publicApi = {
454
- isVisible: isVisible,
455
- onView: processIntervalVisibilityStatus.bind(this, 0)
440
+ onView: initAndVerifyVisibility.bind(this)
456
441
  };
457
442
 
458
443
  return publicApi;
@@ -18,8 +18,6 @@ const TCF2 = {
18
18
  'purpose7': { id: 7, name: 'measurement' }
19
19
  }
20
20
 
21
- const VENDORLESS_MODULE_TYPES = ['fpid-module'];
22
-
23
21
  /*
24
22
  These rules would be used if `consentManagement.gdpr.rules` is undefined by the publisher.
25
23
  */
@@ -125,10 +123,9 @@ function getGvlidForAnalyticsAdapter(code) {
125
123
  * @param {Object} consentData - gdpr consent data
126
124
  * @param {string=} currentModule - Bidder code of the current module
127
125
  * @param {number=} gvlId - GVL ID for the module
128
- * @param {string=} moduleType module type
129
126
  * @returns {boolean}
130
127
  */
131
- export function validateRules(rule, consentData, currentModule, gvlId, moduleType) {
128
+ export function validateRules(rule, consentData, currentModule, gvlId) {
132
129
  const purposeId = TCF2[Object.keys(TCF2).filter(purposeName => TCF2[purposeName].name === rule.purpose)[0]].id;
133
130
 
134
131
  // return 'true' if vendor present in 'vendorExceptions'
@@ -141,14 +138,12 @@ export function validateRules(rule, consentData, currentModule, gvlId, moduleTyp
141
138
  const vendorConsent = deepAccess(consentData, `vendorData.vendor.consents.${gvlId}`);
142
139
  const liTransparency = deepAccess(consentData, `vendorData.purpose.legitimateInterests.${purposeId}`);
143
140
 
144
- const vendorlessModule = includes(VENDORLESS_MODULE_TYPES, moduleType);
145
-
146
141
  /*
147
142
  Since vendor exceptions have already been handled, the purpose as a whole is allowed if it's not being enforced
148
143
  or the user has consented. Similar with vendors.
149
144
  */
150
145
  const purposeAllowed = rule.enforcePurpose === false || purposeConsent === true;
151
- const vendorAllowed = rule.enforceVendor === false || vendorConsent === true || vendorlessModule === true;
146
+ const vendorAllowed = rule.enforceVendor === false || vendorConsent === true;
152
147
 
153
148
  /*
154
149
  Few if any vendors should be declaring Legitimate Interest for Device Access (Purpose 1), but some are claiming
@@ -167,16 +162,15 @@ export function validateRules(rule, consentData, currentModule, gvlId, moduleTyp
167
162
  * @param {Function} fn reference to original function (used by hook logic)
168
163
  * @param {Number=} gvlid gvlid of the module
169
164
  * @param {string=} moduleName name of the module
170
- * @param {string=} moduleType module type
171
165
  */
172
- export function deviceAccessHook(fn, gvlid, moduleName, moduleType, result) {
166
+ export function deviceAccessHook(fn, gvlid, moduleName, result) {
173
167
  result = Object.assign({}, {
174
168
  hasEnforcementHook: true
175
169
  });
176
170
  if (!hasDeviceAccess()) {
177
171
  logWarn('Device access is disabled by Publisher');
178
172
  result.valid = false;
179
- fn.call(this, gvlid, moduleName, moduleType, result);
173
+ fn.call(this, gvlid, moduleName, result);
180
174
  } else {
181
175
  const consentData = gdprDataHandler.getConsentData();
182
176
  if (consentData && consentData.gdprApplies) {
@@ -188,19 +182,19 @@ export function deviceAccessHook(fn, gvlid, moduleName, moduleType, result) {
188
182
  gvlid = getGvlid(moduleName) || gvlid;
189
183
  }
190
184
  const curModule = moduleName || curBidder;
191
- let isAllowed = validateRules(purpose1Rule, consentData, curModule, gvlid, moduleType);
185
+ let isAllowed = validateRules(purpose1Rule, consentData, curModule, gvlid);
192
186
  if (isAllowed) {
193
187
  result.valid = true;
194
- fn.call(this, gvlid, moduleName, moduleType, result);
188
+ fn.call(this, gvlid, moduleName, result);
195
189
  } else {
196
190
  curModule && logWarn(`TCF2 denied device access for ${curModule}`);
197
191
  result.valid = false;
198
192
  storageBlocked.push(curModule);
199
- fn.call(this, gvlid, moduleName, moduleType, result);
193
+ fn.call(this, gvlid, moduleName, result);
200
194
  }
201
195
  } else {
202
196
  result.valid = true;
203
- fn.call(this, gvlid, moduleName, moduleType, result);
197
+ fn.call(this, gvlid, moduleName, result);
204
198
  }
205
199
  }
206
200
  }
@@ -1,4 +1,13 @@
1
- import { isStr, deepAccess, isArray, isNumber, logError, logWarn, parseGPTSingleSizeArrayToRtbSize } from '../src/utils.js';
1
+ import {
2
+ isStr,
3
+ deepAccess,
4
+ isArray,
5
+ isNumber,
6
+ logError,
7
+ logWarn,
8
+ parseGPTSingleSizeArrayToRtbSize,
9
+ mergeDeep
10
+ } from '../src/utils.js';
2
11
  import { registerBidder } from '../src/adapters/bidderFactory.js';
3
12
  import { Renderer } from '../src/Renderer.js';
4
13
  import { VIDEO } from '../src/mediaTypes.js';
@@ -153,9 +162,7 @@ export const spec = {
153
162
  user = {
154
163
  data: [{
155
164
  name: 'iow_labs_pub_data',
156
- segment: jwpseg.map((seg) => {
157
- return {name: 'jwpseg', value: seg};
158
- })
165
+ segment: segmentProcessing(jwpseg, 'jwpseg'),
159
166
  }]
160
167
  };
161
168
  }
@@ -174,9 +181,27 @@ export const spec = {
174
181
  user.ext = userExt;
175
182
  }
176
183
 
184
+ const ortb2UserData = deepAccess(bidderRequest, 'ortb2.user.data');
185
+ if (ortb2UserData && ortb2UserData.length) {
186
+ if (!user) {
187
+ user = { data: [] };
188
+ }
189
+ user = mergeDeep(user, {
190
+ data: [...ortb2UserData]
191
+ });
192
+ }
193
+
177
194
  if (user) {
178
195
  request.user = user;
179
196
  }
197
+ const site = deepAccess(bidderRequest, 'ortb2.site');
198
+ if (site) {
199
+ const data = deepAccess(site, 'content.data');
200
+ if (data && data.length) {
201
+ const siteContent = request.site.content || {};
202
+ request.site.content = mergeDeep(siteContent, { data });
203
+ }
204
+ }
180
205
 
181
206
  if (gdprConsent && gdprConsent.gdprApplies) {
182
207
  request.regs = {
@@ -408,4 +433,20 @@ export function getSyncUrl() {
408
433
  return SYNC_URL;
409
434
  }
410
435
 
436
+ function segmentProcessing(segment, forceSegName) {
437
+ return segment
438
+ .map((seg) => {
439
+ const value = seg && (seg.value || seg.id || seg);
440
+ if (typeof value === 'string' || typeof value === 'number') {
441
+ return {
442
+ value: value.toString(),
443
+ ...(forceSegName && { name: forceSegName }),
444
+ ...(seg.name && { name: seg.name }),
445
+ };
446
+ }
447
+ return null;
448
+ })
449
+ .filter((seg) => !!seg);
450
+ }
451
+
411
452
  registerBidder(spec);
@@ -33,7 +33,7 @@ The following configuration parameters are available:
33
33
 
34
34
  ```javascript
35
35
  pbjs.enableAnalytics({
36
- provider: 'hadron',
36
+ provider: 'hadronAnalytics',
37
37
  options: {
38
38
  partnerId: 1234, // change to the Partner ID you got from Audigent
39
39
  eventsToTrack: ['auctionEnd','bidWon']
@@ -41,8 +41,8 @@ pbjs.enableAnalytics({
41
41
  });
42
42
  ```
43
43
 
44
- | Parameter | Scope | Type | Description | Example |
45
- | --- | --- | --- |---------------------------------------------------------| --- |
46
- | provider | Required | String | The name of this module: `hadronAnalytics` | `hadronAnalytics` |
47
- | options.partnerId | Required | Number | This is the Audigent Partner ID obtained from Audigent. | `1234` |
44
+ | Parameter | Scope | Type | Description | Example |
45
+ |-----------------------|----------|------------------|---------------------------------------------------------|---------------------------|
46
+ | provider | Required | String | The name of this module: `hadronAnalytics` | `hadronAnalytics` |
47
+ | options.partnerId | Required | Number | This is the Audigent Partner ID obtained from Audigent. | `1234` |
48
48
  | options.eventsToTrack | Optional | Array of strings | Overrides the set of tracked events | `['auctionEnd','bidWon']` |
@@ -12,6 +12,7 @@ import { isFn, isStr, isPlainObject, logError } from '../src/utils.js';
12
12
 
13
13
  const MODULE_NAME = 'hadronId';
14
14
  const AU_GVLID = 561;
15
+ const DEFAULT_HADRON_URL_ENDPOINT = 'https://id.hadron.ad.gt/api/v1/pbhid';
15
16
 
16
17
  export const storage = getStorageManager({gvlid: AU_GVLID, moduleName: 'hadron'});
17
18
 
@@ -29,6 +30,15 @@ function paramOrDefault(param, defaultVal, arg) {
29
30
  return defaultVal;
30
31
  }
31
32
 
33
+ /**
34
+ * @param {string} url
35
+ * @param {string} params
36
+ * @returns {string}
37
+ */
38
+ const urlAddParams = (url, params) => {
39
+ return url + (url.indexOf('?') > -1 ? '&' : '?') + params
40
+ }
41
+
32
42
  /** @type {Submodule} */
33
43
  export const hadronIdSubmodule = {
34
44
  /**
@@ -39,8 +49,8 @@ export const hadronIdSubmodule = {
39
49
  /**
40
50
  * decode the stored id value for passing to bid requests
41
51
  * @function
42
- * @param {{value:string}} value
43
- * @returns {{hadronId:Object}}
52
+ * @param {string} value
53
+ * @returns {Object}
44
54
  */
45
55
  decode(value) {
46
56
  let hadronId = storage.getDataFromLocalStorage('auHadronId');
@@ -59,9 +69,12 @@ export const hadronIdSubmodule = {
59
69
  if (!isPlainObject(config.params)) {
60
70
  config.params = {};
61
71
  }
62
- const url = paramOrDefault(config.params.url,
63
- `https://id.hadron.ad.gt/api/v1/pbhid`,
64
- config.params.urlArg);
72
+ const partnerId = config.params.partnerId | 0;
73
+
74
+ const url = urlAddParams(
75
+ paramOrDefault(config.params.url, DEFAULT_HADRON_URL_ENDPOINT, config.params.urlArg),
76
+ `partner_id=${partnerId}&_it=prebid`
77
+ );
65
78
 
66
79
  const resp = function (callback) {
67
80
  let hadronId = storage.getDataFromLocalStorage('auHadronId');
@@ -11,6 +11,9 @@ pbjs.setConfig({
11
11
  usersync: {
12
12
  userIds: [{
13
13
  name: 'hadronId',
14
+ params: {
15
+ partnerId: 1234 // change it to the Partner ID you'll get from Audigent
16
+ },
14
17
  storage: {
15
18
  name: 'hadronId',
16
19
  type: 'html5'
@@ -22,14 +25,15 @@ pbjs.setConfig({
22
25
  ## Parameter Descriptions for the `usersync` Configuration Section
23
26
  The below parameters apply only to the HadronID User ID Module integration.
24
27
 
25
- | Param under usersync.userIds[] | Scope | Type | Description | Example |
26
- | --- | --- | --- | --- | --- |
27
- | name | Required | String | ID value for the HadronID module - `"hadronId"` | `"hadronId"` |
28
- | storage | Required | Object | The publisher must specify the local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. | |
29
- | storage.type | Required | String | This is where the results of the user ID will be stored. The recommended method is `localStorage` by specifying `html5`. | `"html5"` |
30
- | storage.name | Required | String | The name of the cookie or html5 local storage where the user ID will be stored. | `"hadronid"` |
31
- | storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `365` |
32
- | value | Optional | Object | Used only if the page has a separate mechanism for storing the Hadron ID. The value is an object containing the values to be sent to the adapters. In this scenario, no URL is called and nothing is added to local storage | `{"hadronId": "eb33b0cb-8d35-4722-b9c0-1a31d4064888"}` |
33
- | params | Optional | Object | Used to store params for the id system |
34
- | params.url | Optional | String | Set an alternate GET url for HadronId with this parameter |
35
- | params.urlArg | Optional | Object | Optional url parameter for params.url |
28
+ | Param under usersync.userIds[] | Scope | Type | Description | Example |
29
+ |--------------------------------|----------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------|
30
+ | name | Required | String | ID value for the HadronID module - `"hadronId"` | `"hadronId"` |
31
+ | storage | Required | Object | The publisher must specify the local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. | |
32
+ | storage.type | Required | String | This is where the results of the user ID will be stored. The recommended method is `localStorage` by specifying `html5`. | `"html5"` |
33
+ | storage.name | Required | String | The name of the cookie or html5 local storage where the user ID will be stored. | `"hadronid"` |
34
+ | storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `365` |
35
+ | value | Optional | Object | Used only if the page has a separate mechanism for storing the Hadron ID. The value is an object containing the values to be sent to the adapters. In this scenario, no URL is called and nothing is added to local storage | `{"hadronId": "eb33b0cb-8d35-4722-b9c0-1a31d4064888"}` |
36
+ | params | Optional | Object | Used to store params for the id system |
37
+ | params.partnerId | Required | Number | This is the Audigent Partner ID obtained from Audigent. | `1234` |
38
+ | params.url | Optional | String | Set an alternate GET url for HadronId with this parameter |
39
+ | params.urlArg | Optional | Object | Optional url parameter for params.url |
@@ -23,6 +23,15 @@ export const HALOID_LOCAL_NAME = 'auHadronId';
23
23
  export const RTD_LOCAL_NAME = 'auHadronRtd';
24
24
  export const storage = getStorageManager({gvlid: AU_GVLID, moduleName: SUBMODULE_NAME});
25
25
 
26
+ /**
27
+ * @param {string} url
28
+ * @param {string} params
29
+ * @returns {string}
30
+ */
31
+ const urlAddParams = (url, params) => {
32
+ return url + (url.indexOf('?') > -1 ? '&' : '?') + params
33
+ }
34
+
26
35
  /**
27
36
  * Deep set an object unless value present.
28
37
  * @param {Object} obj
@@ -165,8 +174,12 @@ export function getRealTimeData(bidConfig, onDone, rtdConfig, userConsent) {
165
174
  userIds.hadronId = hadronId;
166
175
  getRealTimeDataAsync(bidConfig, onDone, rtdConfig, userConsent, userIds);
167
176
  }
177
+ const partnerId = rtdConfig.params.partnerId | 0;
168
178
  const hadronIdUrl = rtdConfig.params && rtdConfig.params.hadronIdUrl;
169
- const scriptUrl = paramOrDefault(hadronIdUrl, HADRON_ID_DEFAULT_URL, userIds);
179
+ const scriptUrl = urlAddParams(
180
+ paramOrDefault(hadronIdUrl, HADRON_ID_DEFAULT_URL, userIds),
181
+ `partner_id=${partnerId}&_it=prebid`
182
+ );
170
183
  loadExternalScript(scriptUrl, 'hadron', () => {
171
184
  logInfo(LOG_PREFIX, 'hadronIdTag loaded', scriptUrl);
172
185
  })
@@ -44,8 +44,9 @@ pbjs.setConfig(
44
44
  params: {
45
45
  segmentCache: false,
46
46
  requestParams: {
47
- publisherId: 1234
48
- }
47
+ publisherId: 1234 // deprecated, use partnerId instead
48
+ },
49
+ partnerId: 1234
49
50
  }
50
51
  }
51
52
  ]
@@ -56,15 +57,17 @@ pbjs.setConfig(
56
57
 
57
58
  ### Parameter Descriptions for the Hadron Configuration Section
58
59
 
59
- | Name |Type | Description | Notes |
60
- | :------------ | :------------ | :------------ |:------------ |
61
- | name | String | Real time data module name | Always 'hadron' |
62
- | waitForIt | Boolean | Required to ensure that the auction is delayed until prefetch is complete | Optional. Defaults to false |
63
- | params | Object | | |
64
- | params.handleRtd | Function | A passable RTD handler that allows custom adunit and ortb2 logic to be configured. The function signature is (bidConfig, rtd, rtdConfig, pbConfig) => {}. | Optional |
65
- | params.segmentCache | Boolean | This parameter tells the Hadron RTD module to attempt reading segments from a local storage cache instead of always requesting them from the Audigent server. | Optional. Defaults to false. |
66
- | params.requestParams | Object | Publisher partner specific configuration options, such as optional publisher id and other segment query related metadata to be submitted to Audigent's backend with each request. Contact prebid@audigent.com for more information. | Optional |
67
- | params.hadronIdUrl | String | Parameter to specify alternate hadronid endpoint url. | Optional |
60
+ | Name | Type | Description | Notes |
61
+ |:---------------------------------|:---------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------|
62
+ | name | String | Real time data module name | Always 'hadron' |
63
+ | waitForIt | Boolean | Required to ensure that the auction is delayed until prefetch is complete | Optional. Defaults to false |
64
+ | params | Object | | |
65
+ | params.partnerId | Number | This is the Audigent Partner ID obtained from Audigent. | `1234` |
66
+ | params.handleRtd | Function | A passable RTD handler that allows custom adunit and ortb2 logic to be configured. The function signature is (bidConfig, rtd, rtdConfig, pbConfig) => {}. | Optional |
67
+ | params.segmentCache | Boolean | This parameter tells the Hadron RTD module to attempt reading segments from a local storage cache instead of always requesting them from the Audigent server. | Optional. Defaults to false. |
68
+ | params.requestParams | Object | Publisher partner specific configuration options, such as optional publisher id and other segment query related metadata to be submitted to Audigent's backend with each request. Contact prebid@audigent.com for more information. | Optional |
69
+ | params.requestParams.publisherId | Object | (deprecated) Publisher id and other segment query related metadata to be submitted to Audigent's backend with each request. Contact prebid@audigent.com for more information. | Optional |
70
+ | params.hadronIdUrl | String | Parameter to specify alternate hadronid endpoint url. | Optional |
68
71
 
69
72
  ### Publisher Customized RTD Handling
70
73
  As indicated above, it is possible to provide your own bid augmentation
@@ -100,8 +103,9 @@ pbjs.setConfig(
100
103
  },
101
104
  segmentCache: false,
102
105
  requestParams: {
103
- publisherId: 1234
104
- }
106
+ publisherId: 1234 // deprecated, use partnerId instead
107
+ },
108
+ partnerId: 1234
105
109
  }
106
110
  }
107
111
  ]
@@ -42,14 +42,6 @@ function setImDataInCookie(value) {
42
42
  */
43
43
  export function getBidderFunction(bidderName) {
44
44
  const biddersFunction = {
45
- ix: function (bid, data) {
46
- if (data.im_segments && data.im_segments.length) {
47
- config.setConfig({
48
- ix: {firstPartyData: {im_segments: data.im_segments}},
49
- });
50
- }
51
- return bid
52
- },
53
45
  pubmatic: function (bid, data) {
54
46
  if (data.im_segments && data.im_segments.length) {
55
47
  const dctr = deepAccess(bid, 'params.dctr');
@@ -37,9 +37,13 @@ const createOpenRtbRequest = (validBidRequests, bidderRequest) => {
37
37
  source: {tid: bidderRequest.auctionId}
38
38
  };
39
39
 
40
+ // Get the url parameters
41
+ const queryString = window.location.search;
42
+ const urlParams = new URLSearchParams(queryString);
43
+ const checkPrebid = urlParams.get('_checkPrebid');
40
44
  // Force impactify debugging parameter
41
- if (window.localStorage.getItem('_im_db_bidder') != null) {
42
- request.test = Number(window.localStorage.getItem('_im_db_bidder'));
45
+ if (checkPrebid != null) {
46
+ request.test = Number(checkPrebid);
43
47
  }
44
48
 
45
49
  // Set Schain in request